Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/225.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 处理Android碎片事务问题的正确/最佳方法_Java_Android_Android Fragments_Fragment - Fatal编程技术网

Java 处理Android碎片事务问题的正确/最佳方法

Java 处理Android碎片事务问题的正确/最佳方法,java,android,android-fragments,fragment,Java,Android,Android Fragments,Fragment,在我的开源Android应用程序中,发现了一个问题,即一个特定的片段将出现在另一个片段之上,或者在特定情况下使应用程序崩溃 如果您想查看更多信息和示例屏幕截图,请参阅GitHub上的问题: 我已经确定了原因,但想知道android.support.v4.app包中使用哪些方法来解决问题 在MainActivity.java中,是使用FragmentTransaction.replace()切换片段的导航抽屉的代码 出现此问题是因为在MapFragment中,我使用了: ViewMapFragm

在我的开源Android应用程序中,发现了一个问题,即一个特定的片段将出现在另一个片段之上,或者在特定情况下使应用程序崩溃

如果您想查看更多信息和示例屏幕截图,请参阅GitHub上的问题:

我已经确定了原因,但想知道android.support.v4.app包中使用哪些方法来解决问题

MainActivity.java
中,是使用
FragmentTransaction.replace()
切换片段的导航抽屉的代码

出现此问题是因为在
MapFragment
中,我使用了:

ViewMapFragment vmf = new ViewMapFragment();
FragmentTransaction ft = getSherlockActivity().getSupportFragmentManager().beginTransaction();
ft.addToBackStack(null);
ft.replace(R.id.content_frame, vmf);
ft.commit();
ViewMapFragment
onDestroyView()
中:

onDestroyView()
正确地从视图中删除了
ViewMapFragment
,但是如果您看到了它并使用导航抽屉更改为其他片段,
MapFragment
仍在后堆栈中

因此,对于我的问题:

1) 在尝试删除/替换某个特定片段之前,我如何检查该片段是否在后堆栈上,或者如果您尝试在没有任何内容的情况下(即未检查)应用程序是否不会崩溃?例如,当后堆栈上没有任何内容时调用
popBackStack()

2) 我应该使用
FragmentManager
类方法尝试从后堆栈中删除
MapFragment
,还是应该使用
FragmentTransaction
方法?赞成还是反对


3)
popbackbackstack()
popbackbackstackimmediate()
之间的UI有什么区别?用户是否看到一些故障转换?

根据的文档,当您调用addToBackStack方法时,它只会记住您在该事务中执行的操作。当调用popBackStack方法时,它将反转这些操作并执行它们

那么,会发生什么:

  • 当我们从MapFragment转到ViewMapFragment时,FragmentManager会记住删除MapFragment并添加ViewMapFragment操作
  • 然后我们使用导航抽屉转到任何其他片段,这将导致ViewMapFragment删除操作,然后添加从抽屉中选择的片段
  • 最后,当我们按下Back按钮时,调用PopBackbackImmediate,FragmentManager执行相反的操作:ViewMapFragment被删除(实际上它已经被删除),MapFragment被添加。这里出现了问题-所选片段仍然存在,因此我们在屏幕上同时显示了两个片段
  • 处理这种情况有几种选择:

  • 只需将导航抽屉操作添加到后台堆栈
  • 每次导航抽屉启动片段切换时清除后堆栈
  • 要清除后堆栈,可以使用以下代码():

    如果你把这一行放在selectItem方法的开头,错误就会被修复

    你的问题是:

  • 您可以使用方法检查片段是否在后堆栈中。见我答案末尾的例子
  • 从技术上讲,backstack的一个条目可以包含多个片段,我认为没有办法从中删除单个片段。您只需清除后堆栈(请参阅此),而无需删除
  • 主要区别在于,popBackStack将在实际开始弹出过程()之前为您提供一个执行某些操作的机会
  • 例如。例如,我们添加了一个带有标记“fragment-1”的片段:

    然后,我们将其放入后堆栈,并用另一个片段替换它:

    getSupportFragmentManager()
            .beginTransaction()
            .addToBackStack(null)
            .replace(R.id.frame, new TestFragment(), "another-fragment")
            .commit();
    

    此时,getSupportFragmentManager().findFragmentByTag(“fragment-1”)返回我们的第一个片段(它从后堆栈条目中获取)。现在,我们可以通过方法检查此片段是否添加到其活动中-如果返回false,那么我们可以假设该片段位于后堆栈中。

    谢谢您的回答!我将使用您的单线解决方案。作为对您答案的反馈,您没有完全回答问题1,只是在对问题2的回答中间接地回答了问题2,您对问题2的回答可能会更具体地说明在链接答案中的位置,因为我必须梳理该页面上的评论。不幸的是,对于这个问题没有一个好的解决方案(在API中使用clearBackstack方法会很好,但没有这样的方法)。由于这个问题以及清除backstack时出现的转换故障,我不得不在我的项目中实现我自己的backstack系统(我使用的是非常自定义的转换动画)。:(我添加了更多关于1和2个问题的信息。希望这对我有所帮助。
    getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    
    getSupportFragmentManager()
            .beginTransaction()
            .replace(R.id.frame, new TestFragment(), "fragment-1")
            .commit();
    
    getSupportFragmentManager()
            .beginTransaction()
            .addToBackStack(null)
            .replace(R.id.frame, new TestFragment(), "another-fragment")
            .commit();