26

嗨,我正在开发我正在使用的 android 应用程序,我正在使用单个Activity和 3 个片段。所以考虑我有 3 个片段 AB C。当我从 A 切换到 B 时,我正在添加Fragment到 backstack 和类似的 B 到 C。现在当我从 C 点击返回时,它会显示 B 和类似的 B 到 A。

但事情是,当我从 C 到 B 或 B 到 A 时,它不是调用onResume()或任何其他生命周期方法Fragment

我实际上想为每个Fragment我在ActionBar. 因此,在我的代码中,当我从 A 移动到 B 或 B 到 c 时,我正在更改片段内的活动标题。但是当我点击后退时,它并没有因此而改变。

实际问题是什么?为什么从后台弹出后它不调用onResume()我的Fragment?我该如何解决这个问题?需要帮忙。谢谢你。

4

8 回答 8

23

onResume()of the仅在 the恢复Fragment时才被调用。Activity所以这对你没有帮助。即使我现在也面临类似的问题。您可以OnBackStackChangedListener在堆栈顶部实现并获取片段名称,并根据该名称设置ActionBar标题。

private FragmentManager.OnBackStackChangedListener getListener()
{
    FragmentManager.OnBackStackChangedListener result = new FragmentManager.OnBackStackChangedListener()
    {
        public void onBackStackChanged()
        {
            FragmentManager manager = getFragmentManager();

            if (manager != null)
            {
                if(manager.getBackStackEntryCount() >= 1){
                    String topOnStack = manager.getBackStackEntryAt(manager.getBackStackEntryCount()-1).getName();
                    Log.i("TOP ON BACK STACK",topOnStack);
                }
                }
            }
    };

    return result;
}
于 2013-11-27T16:58:36.137 回答
15

尝试在. replace_ 这对我有用:addFragmentTransaction

FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, fragment);
ft.addToBackStack(null);
ft.commit();
于 2013-11-27T15:34:27.020 回答
8

正如其他人已经说过的,onResume()只有在活动本身恢复时才调用,所以这根本没有帮助。

您需要检查是否要添加新片段或替换片段事务中的现有片段:

  • 如果您replace()是以前的片段,则当您返回之前的片段时,它将从头开始重新创建,因此onCreateView()将再次调用,您可以在那里更新您的工具栏标题。你可能已经这样做了。

  • 如果你add()一个新的片段,之前的片段仍然存在,只是不可见。当你回到它时,你可以从后面的堆栈中获取最后一个条目(在片段管理器中使用getBackStackEntryCount()getBackStackEntryAt()),获取相应的片段对象(findFragmentByTag()在片段管理器中使用),将该片段转换为某个基类您的所有片段都将从该片段继承并调用自定义方法,例如onVisible(),在该片段上。基类中的默认实现onVisible()什么也不做。覆盖每个片段以根据需要更新工具栏标题、FAB 和其他任何内容。我也打电话onVisible()onResume()避免代码重复。

于 2018-01-10T18:04:06.920 回答
3

您可以使用这种片段方法:

@Override
public void onHiddenChanged(boolean hidden) {
    super.onHiddenChanged(hidden);
}
于 2018-07-18T20:30:50.480 回答
2

将此代码放入您的片段中。

@Override
public void setUserVisibleHint(boolean visible) {
        super.setUserVisibleHint(visible);
        if (visible && isResumed()) {
            onResume();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (!getUserVisibleHint()) {
            return;
        }
        setData();
    }
于 2017-02-02T06:18:54.050 回答
1

我用这种方式,在你的片段中添加这个块代码

requireActivity().supportFragmentManager.addOnBackStackChangedListener {
            val fm = requireActivity().supportFragmentManager
            fm?.let {
                if (it.backStackEntryCount == YOUR_FRAGMENT_BACK_STACK_INDEX) {
                    // your fragment visible
                }
            }
        }
于 2019-07-31T09:28:57.327 回答
0

其他答案依赖于被命名的特定片段事务,或具有标记片段,依赖于不推荐使用的方法,或将逻辑放入活动中。这使用其视图检测片段在后堆栈上的可见性,根据我的需要,这与onResume. 因为这与位于后堆栈的顶部有关。

用于检测屏幕上是否正在显示视图的视图扩展:(另请参阅How can you tell if a View is visible on screen in Android?

fun View.isVisibleOnScreen(): Boolean {
    if (!isShown) return false
    val actualPosition = Rect().also { getGlobalVisibleRect(it) }
    val screenWidth = Resources.getSystem().displayMetrics.widthPixels
    val screenHeight = Resources.getSystem().displayMetrics.heightPixels
    val screen = Rect(0, 0, screenWidth, screenHeight)
    return Rect.intersects(actualPosition, screen)
}

然后从fragment中定义了一个back stack listener,观察栈顶的fragment(最后添加的那个)

fun Fragment.setOnFragmentStackVisibilityListener(onVisible: () -> Unit) {
    val renderDelayMillis = 300L
    parentFragmentManager.addOnBackStackChangedListener {
        Handler(Looper.getMainLooper()).postDelayed({
            if (isAdded) {
                val topStackFragment = parentFragmentManager.fragments[parentFragmentManager.fragments.size - 1]
                if (topStackFragment.view == view && isVisible && view!!.isVisibleOnScreen()) {
                    onVisible.invoke()
                }
            }
        }, renderDelayMillis)
    }
}

在视图准备好之前调用返回堆栈侦听器,因此需要任意小的延迟。

于 2021-08-26T00:41:28.007 回答
-1

尝试更改onCreateView()片段的标题。

于 2013-10-16T06:43:13.487 回答