与Android片段回栈问题 [英] Problems with Android Fragment back stack

查看:220
本文介绍了与Android片段回栈问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个大问题的方式了Android碎片backstack似乎工作,将最感激提供任何帮助。

I've got a massive problem with the way the android fragment backstack seems to work and would be most grateful for any help that is offered.

想象一下,你有3个片段

Imagine you have 3 Fragments

[1] [2] [3]

我希望用户能够浏览 [1]> [2]≥ [3] ,但在回来的路上(pressing后退键) [3]> [1]

I want the user to be able to navigate [1] > [2] > [3] but on the way back (pressing back button) [3] > [1].

正如我会想到这会通过不调用来完成 addToBackStack(..)创建带给片段交易时, [2] 成XML定义的片段持有人。

As I would have imagined this would be accomplished by not calling addToBackStack(..) when creating the transaction that brings fragment [2] into the fragment holder defined in XML.

这个现实好像,如果我不想 [2] 来再次出现时,用户presses对返回按钮[ 3] ,我不能叫 addToBackStack 中显示片段 [3] 交易。这似乎是完全反直觉的(可能是从iOS的世界即将到来)。

The reality of this seems as though that if I dont want [2] to appear again when user presses back button on [3], I must not call addToBackStack in the transaction that shows fragment [3]. This seems completely counter-intuitive (perhaps coming from the iOS world).

无论如何,如果我做这种方式,当我从 [1]> [2] 和preSS后,我到达回到 [1] 预期。

Anyway if i do it this way, when I go from [1] > [2] and press back I arrive back at [1] as expected.

如果我走了 [1]> [2]≥ [3] 然后preSS回来我跳回 [1] (如预期)。 现在,当我尝试跳奇怪的行为发生[2] 再次[1] 。首先 [3] 短暂显示前 [2] 映入眼帘。如果我preSS回在这一点上 [3] 则显示,如果我preSS回来再次应用程序退出。

If I go [1] > [2] > [3] and then press back I jump back to [1] (as expected). Now the strange behavior happens when I try and jump to [2] again from [1]. First of all [3] is briefly displayed before [2] comes into view. If I press back at this point [3] is displayed, and if I press back once again the app exits.

谁能帮助我了解什么怎么回事?

Can anyone help me to understand whats going on here?


这里是我的主要活动布局的xml文件:


And here is the layout xml file for my main activity:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:orientation="vertical" >

<fragment
        android:id="@+id/headerFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        class="com.fragment_test.FragmentControls" >
    <!-- Preview: layout=@layout/details -->
</fragment>
<FrameLayout
        android:id="@+id/detailFragment"
        android:layout_width="match_parent"
        android:layout_height="fill_parent"

        />





更新 这是导航层次结构的code我用建

Update This is the code I'm using to build by nav heirarchy

    Fragment frag;
    FragmentTransaction transaction;


    //Create The first fragment [1], add it to the view, BUT Dont add the transaction to the backstack
    frag = new Fragment1();

    transaction = getSupportFragmentManager().beginTransaction();
    transaction.replace(R.id.detailFragment, frag);
    transaction.commit();

    //Create the second [2] fragment, add it to the view and add the transaction that replaces the first fragment to the backstack
    frag = new Fragment2();

    transaction = getSupportFragmentManager().beginTransaction();
    transaction.replace(R.id.detailFragment, frag);
    transaction.addToBackStack(null);
    transaction.commit();


    //Create third fragment, Dont add this transaction to the backstack, because we dont want to go back to [2] 
    frag = new Fragment3();
    transaction = getSupportFragmentManager().beginTransaction();
    transaction.replace(R.id.detailFragment, frag);
    transaction.commit();


     //END OF SETUP CODE-------------------------
    //NOW:
    //Press back once and then issue the following code:
    frag = new Fragment2();
    transaction = getSupportFragmentManager().beginTransaction();
    transaction.replace(R.id.detailFragment, frag);
    transaction.addToBackStack(null);
    transaction.commit();

    //Now press back again and you end up at fragment [3] not [1]

感谢

推荐答案

说明(什么是怎么回事?):

EXPLANATION (on what's going on here?):

如果我们记住.replace()=上卸下摆臂()的,加()(我们知道通过文档)

If we keep in mind that .replace() = .remove().add() (that we know by documentation )

替换被添加到容器的现有片段。这是   本质上与调用删除(片段)的所有当前   中加入用相同containerViewId中,然后在加入的片段   加(INT,片段,字符串)这里给出相同的参数。

Replace an existing fragment that was added to a container. This is essentially the same as calling remove(Fragment) for all currently added fragments that were added with the same containerViewId and then add(int, Fragment, String) with the same arguments given here.

然后发生的事情是这个样子(我添加数字,断枝,以使其更清晰):

then what's happening is like this (I'm adding numbers to the frag to make it more clear):

// transaction.replace(R.id.detailFragment, frag1);
Transaction.remove(null).add(frag1)  // frag1 on view

// transaction.replace(R.id.detailFragment, frag2).addToBackStack(null);
Transaction.remove(frag1).add(frag2).addToBackStack(null)  // frag2 on view

// transaction.replace(R.id.detailFragment, frag3);
Transaction.remove(frag2).add(frag3)  // frag3 on view

(这里所有的东西误导开始发生)

(here all misleading stuff starts to happen)

记住.addToBackStack()是只保存交易不是片段本身!

Remember that .addToBackStack() is saving only TRANSACTION not the FRAGMENT as itself!

所以,现在我们已经frag3的布局:

So now we have frag3 on the layout:

< press back button >
// System pops the back stack and find the following saved back entry to be reversed:
// [Transaction.remove(frag1).add(frag2)]
// so the system makes that transaction backward!!!
// tries to remove frag2 (is not there, so it ignores) and re-add(frag1)
// make notice that system doesn't realise that there's a frag3 and does nothing with it
// so it still there attached to view
Transaction.remove(null).add(frag1) //frag1, frag3 on view (OVERLAPPING)

// transaction.replace(R.id.detailFragment, frag2).addToBackStack(null);
Transaction.remove(frag3).add(frag2).addToBackStack(null)  //frag2 on view

< press back button >
// system makes saved transaction backward
Transaction.remove(frag2).add(frag3) //frag3 on view

< press back button >
// no more entries in BackStack
< app exits >

可能的解决方法:

考虑实施<一个href="http://developer.android.com/reference/android/app/FragmentManager.OnBackStackChangedListener.html">FragmentManager.BackStackChangedListener要监视更改在后面堆栈和应用你的逻辑在<一个href="http://developer.android.com/reference/android/app/FragmentManager.OnBackStackChangedListener.html#onBackStackChanged%28%29">onBackStackChanged()梅索德:

consider implementing FragmentManager.BackStackChangedListener to watch for changes in the back stack and apply your logic in onBackStackChanged() methode:

  • 在跟踪交易的数量;
  • 按名称查询特定的交易(FragmentTransaction <一个href="http://developer.android.com/reference/android/app/FragmentTransaction.html#addToBackStack%28java.lang.String%29">addToBackStack(String名));
  • trace a count of transaction;
  • check particular transaction by name (FragmentTransaction addToBackStack(String name));
  • etc.

这篇关于与Android片段回栈问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆