I am trying to call a function when user switch the page to my child fragment. But, when I try to use setUserVisibleHint and onResume, both functions are called from my parent fragment.
First, I set up a view pager in Activity
Then in A1, A3 and B1, I have setUserVisibleHint and onResume functions.
setUserVisibleHint and onResume functions
@Override
public void setUserVisibleHint(boolean visible) {
super.setUserVisibleHint(visible);
Log.d("A1", "setUserVisibleHint"); // A3 for Fragment A3 and B1 for Fragment B1
if (visible && isResumed())
onResume();
}
@Override
public void onResume() {
super.onResume();
Log.d("A1", "onResume"); // A3 for Fragment A3 and B1 for Fragment B1
if (!getUserVisibleHint())
return;
}
Issues:
When I click page B from page A and the view is Fragment B1, I get (This is OK)
D/A1: setUserVisibleHint
D/B1: setUserVisibleHint
D/B1: onResume
When I click page A from page B and the view is Fragment A1, I get (This is OK)
D/B1: setUserVisibleHint
D/A1: setUserVisibleHint
D/A1: onResume
When I click page A from page B and the view is Fragment A3, I get (ISSUE)
D/B1: setUserVisibleHint
D/A1: setUserVisibleHint
D/A1: onResume
I assume that the printout should be like below but I am not sure why the functions called by parent fragment.
D/B1: setUserVisibleHint
D/A3: setUserVisibleHint
D/A3: onResume
Reference
From fragment A1 -> A2,
A2 a2 = new A2();
getFragmentManager().beginTransaction().add(R.id.A1_frameChildFragment, a2)
.addToBackStack(null)
.commit();
From fragment A2 -> A3,
A3 a3 = new A3();
getFragmentManager().beginTransaction().add(R.id.A2_frameChildFragment, a3)
.addToBackStack(null)
.commit();
In ViewPager2 and ViewPager from version androidx. 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.
Retained fragments take advantage of the fact that a fragment's view can be destroyed and recreated without having to destroy the fragment itself. During a configuration change, the FragmentManager first destroys the views of the fragments in its list.
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.
The Fragment class has two callback methods, onAttach() and onDetach() , that you can override to perform work when either of these events occur.
onResume
will not called when you switch between tab in ViewPager
.setUserVisibleHint
will called in the parent fragment of each tab when you switch between in ViewPager
and will not called in child fragment.
This is the default behavior so I think we can not change it.
However, there is a workaround solution. It is sending the visible hint from parent fragment to child fragment
// visible hint in parent fragment
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (!isAdded()) {
return;
}
Fragment fragment = getChildFragmentManager().findFragmentById(R.id.A1_frameChildFragment); // find current child fragment
if (fragment != null) {
fragment.setUserVisibleHint(isVisibleToUser); // send visible from parent to this child fragment
}
}
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