刷新片段不再起作用?

Refresh fragment is not working any more?

我今天浪费了几个小时,因为我的代码不再工作了。 更新到新版本的支持库 25.1.0 后,重新加载片段视图的代码不再有效:

这是我的代码:

FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = manager.beginTransaction();
fragmentTransaction.detach(fragment);
fragmentTransaction.attach(fragment);
fragmentTransaction.commit();

我试过在

上放置一些断点进行调试
public void onPause()
public void onStop()
public void onAttach(Context context)
public void onDetach()  
public void onDestroyView()
public void onDestroy()

但应用程序未进入任何该功能,屏幕上也没有任何反应。

如果我单独调用分离,没有附加,应用程序进入 onPause 和 onStop,视图离开屏幕。

我发现自己也遇到了同样的问题,但在网上找不到答案。最后,我发现在支持库的修订版 25.1.1 中对片段事务添加了一些优化。 (参见 https://developer.android.com/topic/libraries/support-library/revisions.html#25-1-1)。为您的交易禁用那些将使其按预期工作:

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.setAllowOptimization(false);
transaction.detach(fragment).attach(fragment).commitAllowingStateLoss();

更新

setAllowOptimization 已弃用。请改用 setReorderingAllowed

这里是我为使用 getSupportFragmentManager:

所做的细微修改
FragmentTransaction t = getActivity().getSupportFragmentManager().beginTransaction();
t.setAllowOptimization(false);
t.detach(this).attach(this).commitAllowingStateLoss();

@Viad居然回答了问题。补充一点,这发生在 android 版本 26 及更高版本中,默认情况下允许重新排序。当同时请求两个片段操作时,重新排序开始起作用,例如添加片段 1,然后用片段 2 替换它,这只会导致后者(替换片段 2)发生。

因此,当默认允许重新排序时,当使用 detach(fragment).attach(fragment) 重新启动片段时,第一个将被忽略,仅执行第二个。由于片段已经附加,attach(fragment) 不执行任何操作。这就是为什么 none 的片段生命周期方法被调用的原因。

问题的解决方法是 setReorderingAllowed(false) 停用重新排序。所以解决方案是:

                    FragmentTransaction transaction = mActivity.getFragmentManager()
                            .beginTransaction();
                    if (Build.VERSION.SDK_INT >= 26) {
                        transaction.setReorderingAllowed(false);
                    }
                    transaction.detach(fragment).attach
                            (fragment).commit();

将 androidx.navigation 从 2.3.1 更新到 2.3.2 后遇到了类似的问题。

parentFragmentManager.beginTransaction().detach(this).attach(this).commit()

已停止重新加载片段视图。 我在这里找到的所有内容都没有帮助,但我注意到分离和附加操作分别成功执行,我决定将它们的执行分散到不同的 FragmentTransaction 实体:

parentFragmentManager.beginTransaction().detach(this).commit ()
parentFragmentManager.beginTransaction().attach(this).commit ()

它奏效了。 希望这可以节省一些时间。

用Androidx实现片段的刷新有点不同。

根据 Android 开发者文档 here

As a FragmentTransaction is treated as a single atomic set of operations, calls to both detach and attach on the same fragment instance in the same transaction effectively cancel each other out, thus avoiding the destruction and immediate recreation of the fragment's UI. Use separate transactions, separated by executePendingOperations() if using commit(), if you want to detach and then immediately re-attach a fragment.

因此代码必须是这样的:

fun FragmentActivity.relaunchFragment(fragmentId: Int) {
val currentFragment = supportFragmentManager.findFragmentById(fragmentId)
val detachTransaction = supportFragmentManager.beginTransaction()
val attachTransaction = supportFragmentManager.beginTransaction()

currentFragment?.let {
    detachTransaction.detach(it)
    attachTransaction.attach(it)
    detachTransaction.commit()
    attachTransaction.commit()
}

}