简体   繁体   中英

Why am I getting a null value when trying to access a fragment view from the parent activity?

First , I know that there are a lot of similar questions asked about that before , but none of them answers my question .

I'll keep it simple .

I have a class called MainActivity which includes the following code :

public class MainActivity extends AppCompatActivity {
    Car myCar = new Car();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       getSupportFragmentManager().beginTransaction().add(R.id.buttonsContainer,myCar,"me").commitNow();
        View v = myCar.getView(); // returns null
        Button b = v.findViewById(R.id.submitButton); //throws an exception as I'm trying to execute the "findViewById" method on a null object , as the debugger say . 
        b.setText("It works !"); // it doesn't
    }
}

and I have a fragment that includes a single button with the following code :

public class Car extends Fragment {
    View view;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.car, container, false);
        return rootView;
    }
}

It does nothing but showing the layout that corresponds to it.

Here's my MainActivity XML file :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:id="@+id/buttonsContainer"
    tools:context="com.example.myapplication.MainActivity">

</LinearLayout>

And here's my fragment XML code :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <Button
        android:id="@+id/submitButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button" />
</LinearLayout>

What I am trying to do is basically I want to change the button text when it's clicked to something else (it must happen on the parent activity .

I already know how to do it in the fragment activity ) .

I also want to set an onClickListner to that button from MainActivity and not from the fragment activity itself but whenever I try to access that fragment from the main activity I get null value (doesn't matter whether i'm trying to get a reference to its Activity or View as in myCar.getActivity() or MyCar.getView() ) .

Thanks in advance.

Logcat :

AndroidRuntime: FATAL EXCEPTION: main
 Process: com.example.myapplication, PID: 27060
 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myapplication/com.example.myapplication.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
 at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
 at android.app.ActivityThread.-wrap12(ActivityThread.java)
 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
 at android.os.Handler.dispatchMessage(Handler.java:102)
 at android.os.Looper.loop(Looper.java:154)
 at android.app.ActivityThread.main(ActivityThread.java:6119)
 at java.lang.reflect.Method.invoke(Native Method)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
 at com.example.myapplication.MainActivity.onCreate(MainActivity.java:23)
 at android.app.Activity.performCreate(Activity.java:6679)
 at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
 at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
 at android.app.ActivityThread.-wrap12(ActivityThread.java) 
 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
 at android.os.Handler.dispatchMessage(Handler.java:102) 
 at android.os.Looper.loop(Looper.java:154) 
 at android.app.ActivityThread.main(ActivityThread.java:6119) 
 at java.lang.reflect.Method.invoke(Native Method) 
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

Apparently I misunderstood your question. To access a fragment from parent activity the process is similar and this is a way you can achieve that:

MyFragment myFragment;

myFragment = (MyFragment)getSupportFragmentManager().findFragmentByTag("MyFragmentTag");
if(myFragment != null && myFragment.isAdded()) // you need to verify if the instance is actually added to the activity
    myFragment.submitButton.setText("It works");

Your problem is that when you're creating the fragment in code and adding it the view for the fragment won't be inflated yet so it doesn't exist. If you add Log.v("Trace", "End of onCreate"); at the end of onCreate and Log.v("Trace", "Car view inflated"); inside the onCreateView for the Car fragment you will see this in action. What you should do is change it so the button text gets changed inside the inflation of the fragment view. @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View rootView = inflater.inflate(R.layout.fragment_car, container, false); Button b = (Button)rootView.findViewById(R.id.submitButton); b.setText("It works !"); return rootView; }

Try below code for Car Fragment

public class Car extends Fragment {
    View view;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.car, container, false);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Button b = (Button) view.findViewById(R.id.submitButton); //throws an exception as I'm trying to execute the "findViewById" method on a null object , as the debugger say .
        b.setText("It works !"); // it doesn't
    }
}

And MainActivity like

public class MainActivity extends AppCompatActivity {
    Car myCar = new Car();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getSupportFragmentManager().beginTransaction().add(R.id.buttonsContainer,myCar,"me").commit();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM