1

I have a MainActivity with a ViewPager. The ViewPager consists of two Fragments each holding a single RecyclerView. I need to have a reference to the RecyclerView for updating/animating it etc. in the Fragment.

A problem occurs on screen rotation, because for some reason I cannot set the member variable back to the RecyclerView.

public abstract class NotifListFragment extends Fragment {

    protected RecyclerView mRecyclerView;

    public NotifListFragment() {
        // Required empty public constructor
        EventBusHelper.getBus().register(this);
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        mRecyclerView = (RecyclerView) inflater.inflate(R.layout.fragment_notif_list, container, false);
        setupRecyclerView(mRecyclerView);


        return mRecyclerView;
    }

So here in the onCreateView I always inflate the fragment and save the reference in mRecyclerView variable. However, when I later try to access it, it is null.

I am using Otto to call both Fragment's onDataChanged() method. It is called when a button in the RecyclerView is pressed.

@Subscribe
public void onDataChanged(DataChangedEvent event) {
        List<CustomNotification> oldData = ((NotifRecyclerViewAdapter) mRecyclerView.getAdapter()).getmValues();
        List<CustomNotification> newData = getNotifications();
}

The mRecyclerView.getAdapter() is null in this call.

Fragment's getView() also returns null. What is happening?

Martin Melka
  • 7,177
  • 16
  • 79
  • 138
  • 2
    What do you mean "when I later try to access it"? – JanithaR Aug 21 '15 at 10:28
  • I edited the question – Martin Melka Aug 21 '15 at 10:40
  • 1
    How are you sure that onDataChanged is called after onCreateView? – Gaurav Vashisth Aug 21 '15 at 10:44
  • I am logging every time the onCreateView() is called. I rotate the screen, in the log I can see onCreateView() is called and mRecyclerView is not null. Then I click a button in the app. At that point it crashes with mRecyclerView suddenly set to null. – Martin Melka Aug 21 '15 at 10:47
  • Okay, my bad. I should also unregister when onDestroyView() is called, because it seems that with every rotation there are two more Fragments registered to receive the messages, along the old ones. And the old ones don't have any layout anymore, so they throw errors. Sorry. – Martin Melka Aug 21 '15 at 10:54

1 Answers1

0

There are a few things that I found wrong here. Please don't call setupRecyclerView(mRecyclerView); in your onCreateView(), this is something that should be called on your activityCreated() because your fragment might not have been attached to your activity till then. Plus I don't like to do findViewByIds there.

Use the onViewCreated() and onActivityCreated() callbacks. So your code would look something like this.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_notif_list, container, false);
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    mRecycler = (RecyclerView) view.findViewById(R.id.yourId);
}


@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    setupRecyclerView(mRecycler);
}

It's possible that during your call to onDataChanged() that the fragment might not have been added. Do a null check there.

Rakeeb Rajbhandari
  • 5,043
  • 6
  • 43
  • 74