Recyclerview not populating with data after orientation change

牧云@^-^@ 提交于 2020-01-22 16:23:10

问题


I have a recyclerview having different layouts for portrait and landscape. When the activity starts, the recyclerview populates with data irrespective of the orientation. But if the orientation is changed then no data is shown. And no data is shown on consequent orientation changes.

 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Log.d("CCC", "OnCreate View called");
    View view = inflater.inflate(R.layout.fragment_coach_list, container, false);
    new NetworkConnector(getActivity(), coachListURL, method, null, new OnRequestComplete());
    Log.d("CCC", "Network connector called");
    return view;
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    Log.d("CCC", "On View created called");
    //if rv is declared in oncreateview then NPE during setadapter
    coachRecyclerView = (RecyclerView) getActivity().findViewById(R.id.fcoachlist_rv);
    final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
    layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    Log.d("CCC", "orientation " + layoutManager.getOrientation());
    coachRecyclerView.setLayoutManager(layoutManager);
}

private class OnRequestComplete implements RequestCompleteListener<String> {

    public OnRequestComplete() {
    }

    @Override
    public void onRequestExecuted(String responseType, String result) {
        if (!responseType.equals("error")) {
            try {
                JSONObject jsonResponse = new JSONObject(result);
                Log.d("CCC", "Result: " + result);
                String coachResult = jsonResponse.getString("success");
                switch (coachResult) {
                    case "1":
                        ArrayList<CoachList> coachListData = parseJSONResponse(jsonResponse);
                        coachListAdapter = new CoachListAdapter(getActivity());
                        coachListAdapter.setCoachList(coachListData);
                        coachRecyclerView.setAdapter(coachListAdapter);
                        if(coachRecyclerView.getAdapter()== null){
                            Log.d("CCC", "Adapter is null");
                        } else if (coachRecyclerView.getAdapter()== coachListAdapter){
                            Log.d("CCC", "Adapter is coachlistAdapter");
                        } else {
                            Log.d("CCC", "This is odd!!");
                        }
                        Log.d("CCC", "Size " + coachListAdapter.getItemCount());
                        break;
                    case "0":
                        Toast.makeText(getActivity(), "No trainers available currently", Toast.LENGTH_LONG).show();
                        break;
                    case "-1":
                        Toast.makeText(getActivity(), "Please try again later", Toast.LENGTH_LONG).show();
                        break;
                }
            } catch (JSONException e) {
                Log.d("CCC", "CoachList JSONException");
            }
        }
    }
}

NetworkConnector is a class that executes a volley stringrequest.

Here is the logcat when the activity is started and orientation is not changed.

03-18 07:06:57.702 30392-30392/in.jiyofit.the_app D/CCC: OnCreate View called
03-18 07:06:57.722 30392-30392/in.jiyofit.the_app D/CCC: Network connector called
03-18 07:06:57.722 30392-30392/in.jiyofit.the_app D/CCC: On View created called
03-18 07:06:57.722 30392-30392/in.jiyofit.the_app D/CCC: orientation 1
03-18 07:06:57.774 30392-30392/in.jiyofit.the_app W/EGL_genymotion: eglSurfaceAttrib not implemented
03-18 07:06:57.774 30392-30392/in.jiyofit.the_app E/RecyclerView: No adapter attached; skipping layout
03-18 07:06:57.778 30392-30392/in.jiyofit.the_app D/CCC: Result:    {"success":"1","Coaches":[{"CoachID":"1","Coach_Name":"Tyler //lots of json
03-18 07:06:57.778 30392-30392/in.jiyofit.the_app D/CCC: Adapter is coachlistAdapter
03-18 07:06:57.778 30392-30392/in.jiyofit.the_app D/CCC: Size 4
03-18 07:06:57.946 30392-30488/in.jiyofit.the_app D/dalvikvm: GC_FOR_ALLOC freed 414K, 6% free 8585K/9076K, paused 8ms, total 8ms
03-18 07:06:59.426 30392-30392/in.jiyofit.the_app D/CCC: Result:    {"success":"1","Coaches":[{"CoachID":"1","Coach_Name":"Tyler ...//lots of json  
03-18 07:06:59.426 30392-30392/in.jiyofit.the_app D/CCC: Adapter is coachlistAdapter
03-18 07:06:59.426 30392-30392/in.jiyofit.the_app D/CCC: Size 4

Here is the logcat when the orientation is changed.

03-18 07:13:53.792 30392-30392/in.jiyofit.the_app D/CCC: OnCreate View called
03-18 07:13:53.796 30392-30392/in.jiyofit.the_app D/CCC: Network connector called
03-18 07:13:53.796 30392-30392/in.jiyofit.the_app D/CCC: On View created called
03-18 07:13:53.796 30392-30392/in.jiyofit.the_app D/CCC: orientation 1
03-18 07:13:53.796 30392-30392/in.jiyofit.the_app D/CCC: OnCreate View called
03-18 07:13:53.796 30392-30392/in.jiyofit.the_app D/CCC: Network connector called
03-18 07:13:53.796 30392-30392/in.jiyofit.the_app D/CCC: On View created called
03-18 07:13:53.796 30392-30392/in.jiyofit.the_app D/CCC: orientation 1
03-18 07:13:53.856 30392-30392/in.jiyofit.the_app W/EGL_genymotion: eglSurfaceAttrib not implemented
03-18 07:13:53.856 30392-30392/in.jiyofit.the_app E/RecyclerView: No adapter attached; skipping layout
03-18 07:13:53.856 30392-30392/in.jiyofit.the_app E/RecyclerView: No adapter attached; skipping layout
03-18 07:13:53.872 30392-30392/in.jiyofit.the_app D/dalvikvm: GC_FOR_ALLOC freed 554K, 7% free 9823K/10452K, paused 4ms, total 4ms
03-18 07:13:53.888 30392-30392/in.jiyofit.the_app D/CCC: Result:    {"success":"1","Coaches":[{"CoachID":"1","Coach_Name":"Tyler //lots of json
03-18 07:13:53.888 30392-30392/in.jiyofit.the_app D/CCC: Adapter is coachlistAdapter
03-18 07:13:53.888 30392-30392/in.jiyofit.the_app D/CCC: Size 4
03-18 07:13:53.996 30392-30392/in.jiyofit.the_app E/RecyclerView: No adapter attached; skipping layout
03-18 07:13:54.676 30392-30392/in.jiyofit.the_app D/CCC: Result:    {"success":"1","Coaches":[{"CoachID":"1","Coach_Name":"Tyler //lots of json  
03-18 07:13:54.680 30392-30392/in.jiyofit.the_app D/CCC: Adapter is coachlistAdapter
03-18 07:13:54.680 30392-30392/in.jiyofit.the_app D/CCC: Size 4
03-18 07:13:54.736 30392-30392/in.jiyofit.the_app D/CCC: Result:    {"success":"1","Coaches":[{"CoachID":"1","Coach_Name":"Tyler //lots of json  
03-18 07:13:54.736 30392-30392/in.jiyofit.the_app D/CCC: Adapter is coachlistAdapter
03-18 07:13:54.736 30392-30392/in.jiyofit.the_app D/CCC: Size 4

As can be seen, certain parts of the code are getting called repeatedly. I do not know why. OnCreateView is being called again after onViewCreated is called after orientation change. Probably this is causing the issue. Any help would be appreciated. Thanks.


回答1:


This was solved by saving the instance of the fragment in the activity. Saving the state of the layoutmanager in the fragment and restoring it on rotation did not solve this.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //this activity extends baseactivity
    //inflating activity layout in a framelayout inside baseactivity 
    getLayoutInflater().inflate(R.layout.activity_hire_coach, contentFrameLayout);
    if (savedInstanceState != null) {
        //Restore the fragment's instance
        coachListFragment = (CoachListFragment) getFragmentManager().getFragment(savedInstanceState, "coachListFrag");
    } else {
        coachListFragment = new CoachListFragment();
        getFragmentManager().beginTransaction().add(R.id.ahirecoach_layout, coachListFragment, "coachListFragment").commit();
    }
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    //Save the fragment's instance
    getFragmentManager().putFragment(outState, "coachListFrag", coachListFragment);
}

Reference: https://stackoverflow.com/a/17135346/5512020




回答2:


In a fragment, a simple way to retain the data upon rotation is to create your adapter onCreate() there also set the fragment to retain its state setRetainInstance(true). onResume() apply the adapter to your recyclerview, also call adapter.notifyDataSetChanged() to populate your recyclerView. That's how it worked for me.




回答3:


protected void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
// Save list state
mListState = mLayoutManager.onSaveInstanceState();
state.putParcelable(LIST_STATE_KEY, mListState);
}
Restore state in the onRestoreInstanceState():

protected void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);

// Retrieve list state and list/item positions
if(state != null)
mListState = state.getParcelable("myState");
}
Then update the LayoutManager (I do in onResume()):

@Override
protected void onResume() {
super.onResume();

if (mListState != null) {
mLayoutManager.onRestoreInstanceState(mListState);
}
}


来源:https://stackoverflow.com/questions/36083044/recyclerview-not-populating-with-data-after-orientation-change

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!