我想要实现的场景:
我的代码:
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();
}
Run Code Online (Sandbox Code Playgroud)
我的问题:
在按下后退按钮后,infoFrag与之前的detailFrag重叠!为什么?
Jua*_*dor 11
你可以这样做:
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStack(getSupportFragmentManager().getBackStackEntryAt(0).getId(), getSupportFragmentManager().POP_BACK_STACK_INCLUSIVE);
} else {
super.onBackPressed();}
Run Code Online (Sandbox Code Playgroud)
在你的活动中,你要保留第一个片段.
在第一个片段中,你不应该有addToBackStack.但是,其余的,是的.
问题是您backing来自的交易有两个步骤:
infoFragdetailsFrag(即添加的first1详细信息容器)(我们知道因为文档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.)
因此,每当系统恢复时,一个事务正在恢复那两个步骤,并且它没有detailFrag说明添加到它的最后一个,所以它不会对它做任何事情.
我可以在你的案例中考虑两种可能的工作方式:
将您的活动引用到最后使用的detailsFrag并使用BackStackChange监听器,只要值从1更改为0(您必须跟踪以前的值),您还会删除剩下的一个片段
在每个点击监听器上,您将需要popBackStackImmediatly()(以删除上一个事务)和addToBackStack()所有事务.在此变通方法中,您还可以使用一些setCustomAnimation魔法来确保它在屏幕上看起来都很漂亮(例如,使用0到0持续时间1的alpha动画,以避免先前的片段出现并再次消失.
PS.我同意片段管理器/事务应该对它处理.replace()动作的堆栈的方式更加聪明,但这就是它的方式.
编辑:
发生的事情是这样的(我正在为细节添加数字以使其更清晰).记住这一点.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
Run Code Online (Sandbox Code Playgroud)
所以现在我们在布局上有详细信息4:
< 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 !!!
Run Code Online (Sandbox Code Playgroud)
所以问题是系统没有意识到有一个detail4,并且事务是.replace()它应该替换那里的内容.
Budius非常好的解释.我阅读了他的建议并实施了类似的导航,我想与其他人分享.
而不是像这样替换片段:
Transaction.remove(detail1).add(detail2)
Transaction.remove(detail2).add(detail3)
Transaction.remove(detail3).add(detail4)
Run Code Online (Sandbox Code Playgroud)
我在活动布局文件中添加了一个片段容器布局.它可以是LinearLayout,RelativeLayot或者FrameLayout等等.所以在创建活动中我有这个:
transaction.replace(R.id.HomeInputFragment, mainHomeFragment).commit();
Run Code Online (Sandbox Code Playgroud)
mainHomeFragment是按下后退按钮时想要返回的片段,比如infoFrag.然后,在我进行每次下一次交易之前:
fragmentManager.popBackStackImmediate();
transaction.replace(R.id.HomeInputFragment, frag2).addToBackStack(null).commit();
Run Code Online (Sandbox Code Playgroud)
要么
fragmentManager.popBackStackImmediate();
transaction.replace(R.id.HomeInputFragment, frag3).addToBackStack(null).commit();
Run Code Online (Sandbox Code Playgroud)
这样您就不必跟踪当前显示的片段.
| 归档时间: |
|
| 查看次数: |
21744 次 |
| 最近记录: |