Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Child Fragment's setUserVisibleHint and onResume not called

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.

enter image description here

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();
like image 993
Pak Ho Cheung Avatar asked Jan 08 '18 20:01

Pak Ho Cheung


People also ask

How do you know if a fragment is visible?

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.

What are retained fragments?

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.

How do you not start all fragments together on ViewPager when Fragment A is selected?

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.

What are the methods you can override in the fragment class?

The Fragment class has two callback methods, onAttach() and onDetach() , that you can override to perform work when either of these events occur.


1 Answers

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
    }
}
like image 98
Linh Avatar answered Oct 22 '22 17:10

Linh