Click here to Skip to main content
15,898,035 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
why is my fragment `f1` still null even though i added a fragment to my view by `FragmentManager`


MainActivivty.java


    public class MainActivity extends AppCompatActivity implements FragmentA.Communicator {


    FragmentManager manager;
    FragmentA f1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        manager = getSupportFragmentManager();

        Fragment fragment = manager.findFragmentById(R.id.main_fragment_container);
        if (fragment == null) {
            fragment = new FragmentA();
            manager.beginTransaction()
                    .add(R.id.main_fragment_container, fragment)
                    .commit();
        }

        f1 = (FragmentA) manager.findFragmentById(R.id.main_fragment_container);
        f1.setCommunicator(this);

    }

    @Override
    public void changeText(String text) {
        FragmentB f2 = (FragmentB) manager.findFragmentById(R.id.details_fragment_container);

        if (f2 != null && f2.isVisible()) {
            f2.updateText(text);
        } else {
            Intent intent = new Intent(MainActivity.this, DetailsActivity.class);
            intent.putExtra("text", text);
            startActivity(intent);
        }
    }
}


<big>activity_main.xml</big>

    <?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="match_parent">

    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/main_fragment_container" />

</LinearLayout>


DetailsActivity.java 

    public class DetailsActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_details);

        Intent intent = getIntent();
        String recievedText = intent.getStringExtra("text");
        FragmentB f2 = (FragmentB) getSupportFragmentManager().findFragmentById(R.id.details_fragment_container);
        if (f2 != null) {
            f2.updateText(recievedText);
        }

    }
}



details_activity.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.dandroid.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".DetailsActivity">

    <fragment
        android:id="@+id/details_fragment_container"
        android:layout_width="wrap_content"
        android:name="com.example.workout.FragmentB"
        android:layout_height="wrap_content" />

</LinearLayout>



    FragmentA.java

    public class FragmentA extends Fragment {

    Communicator communicator;
    ListView listView;

    public FragmentA() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment


        View view = inflater.inflate(R.layout.fragment_a, container, false);
        listView = view.findViewById(R.id.listview);
        return view;
    }

    public void setCommunicator(Communicator communicator) {
        this.communicator = communicator;
    }

     @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        final ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("first row");
        arrayList.add("second row");
        arrayList.add("third row");

        ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1,
                arrayList);
        listView.setAdapter(adapter);

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                communicator.changeText(arrayList.get(position));
            }
        });
    }

    public interface Communicator {
        void changeText(String text);
    }
}


fragment_a.xml

    <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".FragmentA">

 <ListView
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:id="@+id/listview" />

</FrameLayout>

Log:

    
       java.lang.NullPointerException: Attempt to invoke virtual method 'void 
        com.example.workout.FragmentA.setCommunicator(com.example.workout.FragmentA$Communicator)' 
        on a null object reference
         Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void 
        com.example.workout.FragmentA.setCommunicator(com.example.workout.FragmentA$Communicator)' 
        on a null object reference
        at com.example.workout.MainActivity.onCreate(MainActivity.java:33)
        at android.app.Activity.performCreate(Activity.java:7136)
        at android.app.Activity.performCreate(Activity.java:7127)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78


What I have tried:

i tried many things but nothing worked.
Posted
Updated 6-Nov-19 3:22am
v3
Comments
Richard MacCutchan 6-Nov-19 8:14am    
You should check what gets returned by the fragment manager for f1. The best way to do that is to step through the code with your debugger.
hiwa doski 6-Nov-19 8:48am    
i fixed it by changing
f1 = (FragmentA) manager.findFragmentById(R.id.main_fragment_container);
to
f1 = (FragmentA) fragment;

and it worked but i don't if this is the correct way of doing it.
Richard MacCutchan 6-Nov-19 9:13am    
Sorry, I could not say. But you should still try to find out why the first call fails.
hiwa doski 6-Nov-19 11:08am    
okay, thanks.
Richard MacCutchan 6-Nov-19 11:23am    
See my suggested solution below.

Because it can't find your fragment with that ID: FragmentManager  |  Android Developers[^]
Quote:
Returns
Fragment	The fragment if found or null otherwise.
So use the debugger and see what the ID string you are trying to find actually is.
 
Share this answer
 
Comments
hiwa doski 6-Nov-19 8:49am    
i fixed it by changing
f1 = (FragmentA) manager.findFragmentById(R.id.main_fragment_container);
to
f1 = (FragmentA) fragment;

and it worked but i don't if this is the correct way of doing it.
I think this is the issue:
Java
Fragment fragment = manager.findFragmentById(R.id.main_fragment_container);
if (fragment == null) {
    fragment = new FragmentA();
    manager.beginTransaction()
            .add(R.id.main_fragment_container, fragment)
            .commit();
}

f1 = (FragmentA) manager.findFragmentById(R.id.main_fragment_container);
f1.setCommunicator(this);

In the first instance if manager.findFragmentById returns null then you create a new FragmentA object. But in the second case you do not check to see if you have received a valid object. And looking at the XML I suspect the actual id that is declared is not being recognised as the id of a fragment.
 
Share this answer
 
Comments
hiwa doski 6-Nov-19 12:53pm    
Thanks, but the problem is why it's not receiving a valid object, if i do another check then it will ignore my statements because `f1` will still be null, and i checked id multiple time it's the same one, `FragmentManager` is adding to it and `f1` is receiving from it.
Richard MacCutchan 7-Nov-19 3:29am    
As I mentioned above it is most likely that the search for R.id.main_fragment_container is failing for some reason. That is what you need to investigate.
hiwa doski 7-Nov-19 11:23am    
yeah i found the answer and it's because `commit()` is asynchronous and i need to use `commitNow()` instead

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900