Search code examples
androidandroid-fragmentsandroid-listfragment

NullPointerException in notifyDataSetChanged()


I am trying for last 19 hours to update the listFragment but can't able to get working with notifyDataSetChanged(). I have visited a lot of thread on it but failed to make working it. I have a parent Fragment and inside this I have three ListFragment. The ListFragments need to pass data among them and I am able to do this via interface. Information are being passed successfully. But the ListView is not updating. This is my trying code:

public class SubChaptersListFragment extends SherlockListFragment {

    ArrayAdapter<String> mAdapter = null;
    ArrayList<String> items = new ArrayList<String>();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        int layout = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? android.R.layout.simple_list_item_activated_1
                : android.R.layout.simple_list_item_1;
        Chapter instance = CompetitiveProgramming.chapterList.get(0);
        for (int i = 0; i < instance.subchapterList.size(); i++) {
            items.add(instance.subchapterList.get(i).subChapterTitle);
        }
        mAdapter = new ArrayAdapter<String>(getSherlockActivity(), layout, items);
        setListAdapter(mAdapter);
    }

    @Override
    public void onStart() {
        super.onStart();
        if (getFragmentManager().findFragmentById(
                R.id.sub_sub_category_fragment) != null) {
            getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        }
    }

    // this function is invoked from another `fragment` and position is retrieved successfully
    public void updateList(int position) {
        Chapter instance = CompetitiveProgramming.chapterList.get(position);
        items.clear();
        for (int i = 0; i < instance.subchapterList.size(); i++) {
            items.add(instance.subchapterList.get(i).subChapterTitle);
        }
        mAdapter.notifyDataSetChanged(); // nullpointerException in this line
    }

}

Edit Logcat

08-13 18:33:30.670: E/AndroidRuntime(537): java.lang.NullPointerException
08-13 18:33:30.670: E/AndroidRuntime(537):  at me.kaidul.uhunt.SubChaptersListFragment.updateList(SubChaptersListFragment.java:57)
08-13 18:33:30.670: E/AndroidRuntime(537):  at me.kaidul.uhunt.CompetitiveProgramming.onChapterSelected(CompetitiveProgramming.java:214)
08-13 18:33:30.670: E/AndroidRuntime(537):  at me.kaidul.uhunt.ChaptersListFragment.onListItemClick(ChaptersListFragment.java:60)
08-13 18:33:30.670: E/AndroidRuntime(537):  at android.support.v4.app.ListFragment$2.onItemClick(ListFragment.java:58)
08-13 18:33:30.670: E/AndroidRuntime(537):  at android.widget.AdapterView.performItemClick(AdapterView.java:284)
08-13 18:33:30.670: E/AndroidRuntime(537):  at android.widget.ListView.performItemClick(ListView.java:3382)
08-13 18:33:30.670: E/AndroidRuntime(537):  at android.widget.AbsListView$PerformClick.run(AbsListView.java:1696)
08-13 18:33:30.670: E/AndroidRuntime(537):  at android.os.Handler.handleCallback(Handler.java:587)

This is how I called the fragment from parentFragment:

@Override
public void onChapterSelected(int position) {
    SubChaptersListFragment subChapterFrag = new SubChaptersListFragment();
    if ( subChapterFrag != null) {
        subChapterFrag.updateList(position);
    } else {

    }

}

Solution

  • Your problem is much deeper than a simple null pointer.

    The symptom of your problem is that mAdapter is null when updateList() is called. The bigger problem is that SubChaptersListFragment hasn't been created when CompetitiveProgramming.onChapterSelected() calls updateList().

    You are likely making direct references from one fragment (ChaptersListFragment) to another (SubChaptersListFragment) without considering the lifecycle.

    You need to make sure that the fragment is created and attached to an activity before making any calls to it. I would suggest using the activity's FragmentManager to check for the existence of a fragment and creating it if necessary.