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
Fragments — Scenario 3: Activity with retained Fragment is rotated. The fragment is not destroyed nor created after the rotation because the same fragment instance is used after the activity is recreated. The state bundle is still available in onActivityCreated .
fragment:fragment:1.1. 0 you can just use onPause and onResume callbacks to determine which fragment is currently visible for the user. onResume callback is called when fragment became visible and onPause when it stops to be visible.
Using an OnPageChangeListener in your View Pager, you can detect which fragment is currently shown in the View Pager. You'll then need to check which fragment is shown and then call a method on that fragment's class to start any sounds for example that you don't want to start until the fragment is the fragment in view.
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.
I think you can declare a variable and check the status to true on swipe action.
viewPager.addOnPageChangeListener(new OnPageChangeListener() {
public void onPageScrollStateChanged(int state) {}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
public void onPageSelected(int position) {
// here assign the variable to true;
// This method will get called only after a swipe action is invoked on
//viewpager.
}});
Inside your fragment check whether the variable status is true, if so it's not getting generated from orientation, then reset the variable to false.
Happy coding :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With