【问题标题】: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

标签: android android-fragments fragment android-support-library


【解决方案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()
    }
    

    }

    【讨论】:

      猜你喜欢
      • 2020-04-03
      • 2018-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多