11

I have fragment contains recyclerview in main activity

Fragment.java

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle   savedInstanceState) {
    super.onCreate(savedInstanceState);
    View view  = inflater.inflate(R.layout.activity_main, container, false);
    initInstances(view);
    setRetainInstance(true);
    return view;
}

private void initInstances(View view) {
    mRecyclerView = (RecyclerView) view.findViewById(R.id.dialogList);
    mLayoutManager = new LinearLayoutManager(getActivity());
    mRecyclerView.setLayoutManager(mLayoutManager);
    adapter = new MyAdapter(items);
    mRecyclerView.setAdapter(mAdapter);
}

MainActivity.java

in onCreate method:

myFragment = (MyFragment) getSupportFragmentManager().findFragmentByTag(MyFragment.TAG);
if (MyFragment == null) {
    MyFragment = new MyFragment();
    getSupportFragmentManager().beginTransaction().add(R.id.content_frame,
            myFragment, MyFragment.TAG).commit();
}

But when orientation changed, my RecyclerView redrawn.

I've tried save state with overriding onSaveInstanceState and onRestoreInstanceState like this How to prevent custom views from losing state across screen orientation changes or Saving and restoring view state android, but to no avail for me

How to correctly save state of RecyclerView and adapter's items when orientation change?

SOLUTION: My fragment extends from BaseFragment with some methods:

public class BaseFragment extends Fragment{
Bundle savedState;

public BaseFragment() {
    super();
    if (getArguments() == null)
        setArguments(new Bundle());
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    if (!restoreStateFromArguments()) {
        onFirstTimeLaunched();
    }
}

protected void onFirstTimeLaunched() {

}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    saveStateToArguments();
}



public void saveStateToArguments() {
    if (getView() != null)
        savedState = saveState();
    if (savedState != null) {
        Bundle b = getArguments();
        b.putBundle("internalSavedViewState8954201239547", savedState);
    }
}



private boolean restoreStateFromArguments() {
    Bundle b = getArguments();
    savedState = b.getBundle("internalSavedViewState8954201239547");
    if (savedState != null) {
        onRestoreState(savedState);
        return true;
    }
    return false;
}

private Bundle saveState() {
    Bundle state = new Bundle();
    onSaveState(state);
    return state;
}

protected void onRestoreState(Bundle savedInstanceState) {

}

protected void onSaveState(Bundle outState) {

}

@Override
public void onStart() {
    super.onStart();
}

@Override
public void onStop() {
    super.onStop();
}


@Override
public void onDestroyView() {
    super.onDestroyView();
    saveStateToArguments();
}

In my fragment I override methods and save state of mLayoutManager

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);
}

    @Override
protected void onSaveState(Bundle outState) {
    super.onSaveState(outState);
    outState.putParcelable("myState", mLayoutManager.onSaveInstanceState());
}

@Override
protected void onRestoreState(Bundle savedInstanceState) {
    super.onRestoreState(savedInstanceState);
    mLayoutManager.onRestoreInstanceState(savedInstanceState.getParcelable("myState"));
}
Tobias Ribizel
  • 5,331
  • 1
  • 18
  • 33
Ilnar Karimov
  • 339
  • 2
  • 6
  • 19
  • The lack of uniformity between config changes and the fragment backstack is an absolute nightmare. Thanks for the idea. This seems to have solved my problems for now. – Jimeux Oct 17 '15 at 14:23

1 Answers1

-2

I searched how to get the scroll position of the RecyclerView, but didn't see where I can retrieve it, so I think the best solution is to handle rotation changes directly in your java code, and preventing your activity to restart on orientation change.

To prevent restarting on orientation change, you can follow this solution.

After preventing your Activity from restart, you can build 2 xml layout files, one for portrait mode, and one for landscape mode, you add a FrameLayout in both xml files, holding the place for your RecyclerView.

When the onConfigurationChange(Configuration newConfig) method is called, you call setContentView(int layoutFile) with the appropriate LayoutFile following the new orientation, and add your RecyclerView you are holding in a member of your class in the FrameLayout.

Community
  • 1
  • 1
Louis CAD
  • 10,965
  • 2
  • 39
  • 58