【问题标题】:DialogFragment shows onBack button press even if I remove itDialogFragment 显示 onBack 按钮按下,即使我删除它
【发布时间】:2015-01-12 19:40:09
【问题描述】:

我使用以下代码来显示和取消对话框片段:

public static void showDialogFragment(FragmentManager fm,String type){

    FragmentTransaction ft = fm.beginTransaction();
    MyDialogFragment prev = (MyDialogFragment)fm.findFragmentByTag(type);
    if (prev != null) {
        prev.dismissAllowingStateLoss();
        ft.remove(prev);
    }
    ft.addToBackStack(null);
    MyDialogFragment newFragment = MyDialogFragment.newInstance();
    try{
        newFragment.show(ft,type);
    }catch(IllegalStateException e){
         return;
    }
}



public static void cancelDialogFragment(FragmentManager fm,String tag){
    FragmentTransaction ft = fm.beginTransaction();
    MyDialogFragment prev = (MyDialogFragment )fm.findFragmentByTag(tag);
    if (prev != null) {
        prev.dismiss();
        ft.remove(prev);

    }
    ft.addToBackStack(null);
    ft.commit();

}

当我打开活动时,我会显示一个 dialogFragment,在从 Internet 接收数据后,我会取消它并显示收到的数据,但是如果我再次按下返回按钮,它会显示 dialogFragment,我必须再次按下返回按钮关闭它,然后再完成一次活动。我知道我可以覆盖onBackPressed,但我想知道为什么会这样?为什么要再次显示对话框片段?

我的代码有什么问题?

【问题讨论】:

  • 尝试删除ft.addToBackStack(null);
  • @Rohit5k2 但是我已经从文档中复制了,为什么要删除它?
  • 可以贴出活动类的代码吗?
  • 您所做的是在showDialogFragment() 中将此片段添加到 FragmentManager 到 backstack。然后在cancelDialogFragment() 方法中,您使用ft.remove(prev); 将其从后台堆栈中删除,所以现在,您的后台堆栈与显示DialogFragment 之前一样。但接下来要做的是,再次将此 DialogFragment 添加到 backstack。它没有显示,但它位于 backstack 的顶部。这意味着,如果您按下 backButton,则会显示 backstack 中的顶部项目,即您的 DialogFragment。在下一次 BackPress 中,您的 DialogFragment 将被关闭。
  • 您似乎显然不了解您正在使用的代码。我建议您阅读更多文档并自己试验代码,方法是注释掉并添加行以更好地理解它。

标签: android android-activity back-stack dialogfragment


【解决方案1】:

您所做的是在showDialogFragment() 中将此片段添加到 FragmentManager 到 backstack。然后在cancelDialogFragment() 方法中,您使用ft.remove(prev); 将其从后台堆栈中删除

所以现在,您的后台堆栈与显示 DialogFragment 之前一样。

但是接下来要做的是,再次将此 DialogFragment 添加到 backstack。它没有显示,但它位于 backstack 的顶部。这意味着,如果您按下 backButton,则会显示 backstack 中的顶部项目,即您的 DialogFragment。在下一次 BackPress 中,您的 DialogFragment 将被关闭。

所以不要在cancelDialogFragment() 方法中将片段添加到后台堆栈。

删除这一行:

ft.addToBackStack(null);

【讨论】:

  • 但是为什么我在调用cancel后使用MyDialogFragment prev = (MyDialogFragment )fm.findFragmentByTag(tag);,prev为null呢?
【解决方案2】:

用这个替换你的整个 cancelDialogFragment:

public static void cancelDialogFragment(FragmentManager fm,String tag){
    fm.popBackStack();
}

【讨论】:

  • 真是个坏主意,因为我不知道 backStack 的顶部是什么,而且我问为什么会发生这种情况?
  • 我很抱歉。请原谅我试图提供帮助。请告诉我,在显示对话框时您正在执行多少个片段事务?嗯!
【解决方案3】:

终于找到了原因和正确答案。问题在于:

ft.addToBackStack(null); 

来自文档:

将此事务添加到后台堆栈。这意味着 事务提交后会被记住,并会反转 它的操作后来从堆栈中弹出。

参数名称 此返回堆栈状态的可选名称,或 null。

那个意思:

嘿 android 我已经从 backstack 中删除了 dialogfragment(所以 backStack 顶部没有任何内容,@Vojtaaa9 的答案是错误的,因为我在您运行 MyDialogFragment prev = (MyDialogFragment )fm.findFragmentByTag(tag); 之后添加了评论调用 cancel 你会得到 null,这意味着 backStack 没有任何 dialogfragment)但是记住我的动作,记住有一个 dialogfragment 但现在它已经被删除了。当用户按下后退按钮时,事务反转,这意味着 现在 backStack 顶部没有任何内容 但是随后 android 将一个 dialogFragment 推送到 backStack 以以相反的顺序进行事务.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多