android-fragments 刷新片段不再起作用?

hjqgdpho  于 2022-11-14  发布在  Android
关注(0)|答案(5)|浏览(195)

我今天损失了几个小时,因为我的代码不再工作了。更新到新版本的支持库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()

但应用程序没有进入任何功能,屏幕上也没有任何React。
如果我单独调用detach,而不调用attach,应用程序将进入onPause和onStop,视图将离开屏幕。

xmjla07d

xmjla07d1#

在将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 ()

而且成功了希望这能为某人节省一些时间。

c0vxltue

c0vxltue2#

我发现自己也面临着同样的问题,但在网上找不到答案。最后,我发现在支持库的修订版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

33qvvth1

33qvvth13#

@Viad实际上回答了这个问题。为了补充一点,这发生在android版本26和更高版本中,默认情况下允许重新排序。当两个片段操作同时请求时,重新排序就开始发挥作用,例如添加片段1,然后用片段2替换它,这只会导致后者(替换片段2)发生。
因此,当默认允许重新排序时,当使用detach(fragment).attach(fragment)重新启动片段时,第一个将被忽略,只执行第二个。由于片段已经被附加,attach(fragment)不会做任何事情。这就是为什么没有调用片段的生命周期方法。
问题的解决方案是使用setReorderingAllowed(false)来停用重新排序。因此解决方案是:

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

h7appiyu4#

下面是我为使用getSupportFragmentManager所做的一个小修改:

FragmentTransaction t = getActivity().getSupportFragmentManager().beginTransaction();
t.setAllowOptimization(false);
t.detach(this).attach(this).commitAllowingStateLoss();
vnzz0bqm

vnzz0bqm5#

用Androidx来实现片段的刷新有点不同。
根据Android开发人员文档here
由于FragmentTransaction被视为一个原子操作集,因此在同一事务中对同一片段示例的detach和attach调用可以有效地相互抵消,从而避免破坏和立即重新创建片段的UI。如果要分离片段,然后立即重新附加片段,请使用单独的事务,如果使用commit(),请使用executePendingOperations()进行分隔。
因此,代码必须是这样的:

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()
}

}

相关问题