Child Fragment的setUserVisibleHint和onResume未被调用

时间:2018-01-08 20:55:49

标签: android android-fragments android-viewpager visibility

当用户将页面切换到我的子片段时,我试图调用一个函数。但是,当我尝试使用setUserVisibleHint和onResume时,两个函数都是从我的父片段调用的。

enter image description here

首先,我在Activity

中设置了一个视图寻呼机

然后在A1,A3和B1中,我有setUserVisibleHint和onResume函数。

setUserVisibleHint和onResume函数

@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;
}

的问题:

当我从第A页单击页面B并且视图是片段B1时,我得到(这没关系)

D/A1: setUserVisibleHint
D/B1: setUserVisibleHint
D/B1: onResume

当我从第B页单击页面A并且视图是片段A1时,我得到(这没关系)

D/B1: setUserVisibleHint
D/A1: setUserVisibleHint
D/A1: onResume

当我从第B页单击页面A并且视图是片段A3时,我得到(问题)

D/B1: setUserVisibleHint
D/A1: setUserVisibleHint
D/A1: onResume

我认为打印输出应该如下所示,但我不确定为什么父片段调用的函数。

D/B1: setUserVisibleHint
D/A3: setUserVisibleHint
D/A3: onResume

参考

来自片段A1 - > A2,

A2 a2 = new A2();
getFragmentManager().beginTransaction().add(R.id.A1_frameChildFragment, a2)
    .addToBackStack(null)
    .commit();

来自片段A2 - > A3,

A3 a3 = new A3();
getFragmentManager().beginTransaction().add(R.id.A2_frameChildFragment, a3)
    .addToBackStack(null)
    .commit();

5 个答案:

答案 0 :(得分:5)

当您在onResume中的标签之间切换时,

ViewPager 将无法调用
当您在setUserVisibleHint之间切换时,ViewPager 会在每个标签的父片段中调用。在子片段中不会调用。 这是默认行为,所以我认为我们无法改变它。

但是,有一种解决方法。它将可见提示从父片段发送到子片段

// 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
    }
}

答案 1 :(得分:3)

现在不推荐使用setOnPageChangeListener方法,而是使用addOnPageChangeListener

viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
    @Override
    public void onPageSelected(int position) {
        // do your work
    } 
});

答案 2 :(得分:0)

尝试将来电add更改为replace

A2 a2 = new A2();
getFragmentManager().beginTransaction().replace(R.id.A1_frameChildFragment, a2)
    .addToBackStack(null)
    .commit();

答案 3 :(得分:0)

为此,您必须在加载/单击标签栏/标签视图时调用您的片段。

就像你的情况一样,所有片段都会同时加载,因此当你更改片段时,它不会在课堂上提供任何事件。

对于我的应用程序,我遇到了同样的问题,所以当我点击选项卡然后在调用片段之后加载片段并将提供事件。

答案 4 :(得分:0)

首先总是从Activity开始或创建片段。因为Fragment基本上是您的活动的实例或部分。这就是为什么,总是从Activity上下文而不是Fragment开始或创建片段,以便更好地控制片段生命周期。

例如从FragmentA开始FragmentBActivity中创建一个方法,

public void startFragmentB(){
   FragmentManager manager = getSupportFragmentManager();
   FragmentB fragment = new FragmentB();
   FragmentTransaction transaction = manager.beginTransaction();
   transaction.replace(R.id.container, fragment).addToBackStack("tag");
   transaction.commit();
}

现在,您要在FragmentB中启动或创建FragmentA,只需从您的活动中调用上述方法,

((YourActivity) getActivity()).startFragmentB();