I have an Activity
with ViewPager
. the ViewPager
have a lot of pages, Just like a book. Each fragment has RecyclerViews
with a lot of content. The following is my use case
1 - When I swipe page, RecyclerView must start from the beginning of the list. 2. If I rotate my device, It should read from exact last position of where I left before rotation.
If I don't use any logic, 2nd scenario works perfectly. ie, rotation. But not the first scenario.
If I do some logic like below. Helps to achieve first scenario, But not the second scenario.
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
if (savedInstanceState==null) {
mIsFirstTime = true;
}
}
@Override
public void onResume() {
super.onResume();
try {
getActivity().invalidateOptionsMenu();
if (!mIsFirstTime) {
mListView.scrollToPosition(0);
}
} catch (Exception e) {
e.printStackTrace();
}
}
So My question is
How can I determine a fragment restart is due to screen rotation or Viewpager swipe?
I already tried onConfigurationChanged(Configuration newConfig)
. But it doesn't help me. Could you please help me
From a comment of OP:
My question is how I know that
onSaveInstanceState()
is called due to screen orientation change and not fragment restart
You can do that via Activity#isChangingConfigurations()
API.
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (isChangingConfigurations()) {
// this callback is executed as a result of a configuration change (e.g. orientation change)
} else {
// no configuration change happens (e.g. a click on a home button would end up here)
}
}
Now you can save a boolean value into Bundle outState
and appropriate setup UI after recreation:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("isConfigurationChange", isChangingConfigurations());
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// initialization logics here
if (savedInstanceState != null) {
boolean isConfigurationChange = savedInstanceState.getBoolean("isConfigurationChange");
// if `onCreate` is called as a result of configuration change
if (isConfigurationChange) {
// view hierarchy is not yet laid out, have to post an action
listView.post(new Runnable() {
@Override
public void run() {
// we are guaranteed, that `listView` is already laid out
listView.scrollToPosition(0);
}
});
}
}
}
Note, that performing boolean value checking logics inside onResume()
is a bug (pressing home button and navigating back to the app would result in scrolling to the top again, which is not desired). Instead onCreate()
should be chosen as a correct callback.