刷新片段不再工作

时间:2016-12-21 19:51:26

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

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

5 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:2)

@Viad实际上回答了问题。要添加一点,这发生在android 26及更高版本中,默认情况下允许重新排序。当同时执行两个片段操作时,例如,添加片段1,然后将其替换为片段2,则重新排序才起作用。片段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();

答案 2 :(得分:1)

非常感谢你。这是我使用getSupportFragmentManager

进行的一些细微修改
FragmentTransaction t = getActivity().getSupportFragmentManager().beginTransaction();
t.setAllowOptimization(false);
t.detach(this).attach(this).commitAllowingStateLoss();

答案 3 :(得分:1)

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

#include <stdio.h>

int main()
{
    char i[150];
    char s[150];
    printf("Enter first char : ");
    scanf("%s[^\n]",i);//scan the first string
    printf("Enter second char : ");
    scanf("%s[^\n]",s);//scan the second string
    printf("%s", i);
    printf("\n");
    printf("%s", s);
    printf("\n");
    printf("%c",i[1]);//if you want to print the second caracter in the string i
    printf("\n");
    printf("%c",s[0]);//if you want to print the first caracter in the string s
}

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

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

成功了。 希望这可以节省一些时间。

答案 4 :(得分:1)

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

根据 Android 开发者文档 here

<块引用>

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

所以代码一定是这样的:

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

}