问题描述
情景我想要实现的:
- 装载活动有两个框架集装箱(物品的清单和详细信息)。
- 在应用程序启动时间listFrame和detailsFrame容器一些初始infoFragment添加listFragment。
- 通过列表项导航无添加的每一个细节的事务来支持堆叠(要保持在堆栈中仅infoFragment)。
- 只要用户打后退按钮(导航回),他将回退到intial infoFragment什么加在推出的时间。
- 如果连续后退导航休耕然后应用服务的出口。
我的code:
protected override void OnCreate(Bundle savedInstanceState)
{
...
var listFrag = new ListFragment();
var infoFrag = new InfoFragment();
var trans = FragmentManager.BeginTransaction();
trans.Add(Resource.Id.listFrame, listFrag);
trans.Add(Resource.Id.detailsFrame, infoFrag);
trans.Commit();
...
}
public void OnItemSelected(int id)
{
var detailsFrag = DetailFragment.NewInstance(id);
var trans = FragmentManager.BeginTransaction();
trans.Replace(Resource.Id.detailsFrame, detailsFrag);
if (FragmentManager.BackStackEntryCount == 0)
{
trans.AddToBackStack(null);
}
trans.Commit();
}
我的问题:
在返回按钮被击中,infoFrag是重叠的previous detailFrag!为什么呢?
After back button has been hit, infoFrag is overlapped with previous detailFrag! Why?
推荐答案
的问题是,你是交易备份
的有两个步骤:
The problem is that the transaction that you're backing
from have two steps:
- 删除
infoFrag
- 添加
detailsFrag
(即添加的first1细节容器)
- remove
infoFrag
- add
detailsFrag
(that is the first1 detail container that was added)
(我们知道,因为文档这在本质上是一样的调用remove(片段)的添加具有相同containerViewId所有当前已添加的片段,然后添加(INT,片段,字符串)与相同的参数在这里给出。
)
(we know that because the documentation 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.
)
所以只要系统恢复一个事务正恢复完全相同的2个步骤,它说什么了最近 detailFrag
已添加到它,所以它不做任何事情吧。
So whenever the system is reverting that one transaction is reverting exactly those 2 steps, and it say nothing about the last detailFrag
that was added to it, so it doesn't do anything with it.
这里有两种可能的变通,我能想到你的案件:
There're two possible work arounds I can think on your case:
-
请根据您的活动到最后detailsFrag参考使用,使用BackStackChange监听器,只要从1到0的值的变化(你必须跟踪previous值),也删除一个保留的片段
Keep a reference on your activity to the last detailsFrag used and use the BackStackChange listener to whenever the value change from 1 to 0 (you'll have to keep track of previous values) you also remove that one remaining fragment
在每一次点击监听器,你就必须popBackStackImmediatly()(删除previous交易)和 addToBackStack()
上的所有交易。在此解决方法,你也可以使用一些setCustomAnimation魔法,以确保这一切看起来不错,在屏幕上(例如,使用奥飞动漫从0到0时长1避免previous片段出现,再消失。
on every click listener you'll have to popBackStackImmediatly() (to remove the previous transaction) and addToBackStack()
on all transactions. On this workaround you can also use some setCustomAnimation magic to make sure it all looks nice on the screen (e.g. use a alpha animation from 0 to 0 duration 1 to avoid previous fragment appearing and disappearing again.
PS。我同意片段经理/交易应该多一点聪明,它处理回堆栈.replace()动作的方法,但这是它的方式。
ps. I agree that the fragment manager/transaction should be a bit more clever to the way it handles back stack on .replace() actions, but that's the way it does it.
编辑:
正在发生的事情是这个样子(我添加号码的细节,使之更加清楚)。请记住, .replace()=上卸下摆臂()。增加()
what is happening is like this (I'm adding numbers to the details to make it more clear).Remember that .replace() = .remove().add()
Transaction.remove(info).add(detail1).addToBackStack(null) // 1st time
Transaction.remove(detail1).add(detail2) // 2nd time
Transaction.remove(detail2).add(detail3) // 3rd time
Transaction.remove(detail3).add(detail4) // 4th time
所以现在我们已经detail4的布局:
so now we have detail4 on the layout:
< Press back button >
System pops the back stack and find the following back entry to be reversed
remove(info).add(detail1);
so the system makes that transaction backward.
tries to remove detail1 (is not there, so it ignores)
re-add(info) // OVERLAP !!!
所以问题是,该系统并没有意识到,有一个detail4,而且交易是.replace(),它应该取代无论是在那里。
so the problem is that the system doesn't realise that there's a detail4 and that the transaction was .replace() that it was supposed to replace whatever is in there.
这篇关于如何只保留第一回栈(片段重叠)加入片段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!