刷新片段不再起作用?

Posted

技术标签:

【中文标题】刷新片段不再起作用?【英文标题】:Refresh fragment is not working any more? 【发布时间】:2017-05-07 08:29:44 【问题描述】:

我今天浪费了几个小时,因为我的代码不再工作了。 更新到支持库 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 并且视图离开屏幕。

【问题讨论】:

你应该把它分成一个问题,然后回答你自己的问题。不要把问题和答案放在一起,会混淆。 谢谢!一段时间后,您应该能够将其标记为已接受的答案。 @AidaIsay :不,我只是恢复到库支持修订版 25.0.1 【参考方案1】:

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

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

【讨论】:

除此之外,没有其他解决方案对我有用。真正节省了我的时间。非常感谢【参考方案2】:

我发现自己面临同样的问题,但在网上找不到答案。最后我发现在支持库的修订版 25.1.1 中,对 Fragment Transactions 添加了一些优化。 (见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

【讨论】:

你为什么建议使用commitAllowingStateLoss 而不是commit【参考方案3】:

@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();

【讨论】:

SDK版本> 25的问题让我抓狂,谢谢!【参考方案4】:

这里是我使用getSupportFragmentManager做的一个小改动:

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

【讨论】:

【参考方案5】:

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

根据 Android 开发者文档here

因为 FragmentTransaction 被视为单个原子集 操作,对同一片段的分离和附加调用 同一事务中的实例有效地相互抵消, 从而避免破坏和立即重建 片段的用户界面。使用单独的事务,由 如果使用 commit(),如果要分离,则执行 PendingOperations() 然后立即重新附加一个片段。

因此代码必须是这样的:

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

【讨论】:

以上是关于刷新片段不再起作用?的主要内容,如果未能解决你的问题,请参考以下文章

添加图像后 UIButtonTypeCustom 不再起作用

为啥预编译资产不再起作用?

SoundCloud Android 显式 Intent 共享不再起作用

为啥自定义 CSS 文件不再起作用? [关闭]

添加了 IBOutlet 和自定义 TableViewCell 不再起作用

为啥这个 CSS 过渡速记不再起作用了?