使用 FragmentTransaction.attach() 和 detach() 时不保留 Fragment ui
Posted
技术标签:
【中文标题】使用 FragmentTransaction.attach() 和 detach() 时不保留 Fragment ui【英文标题】:Fragment ui is not retained when using FragmentTransaction.attach() and detach() 【发布时间】:2013-03-03 07:56:23 【问题描述】:根据我对文档的理解,您可以分离片段并稍后重新附加它,它会自动看起来与分离时相同。还有比这更多的吗?我有一个简单的操作栏,带有 2 个按钮,用于 2 个不同的片段。当我从第一个切换到第二个回到第一个时,在第一个片段中加载的图像不再可见。我是否错误地使用了附加/分离,或者我是否需要自己管理 instanceState 并重绘 ui。如果是这样,附加和分离方法的意义何在?
@Override
public void onStart()
super.onStart();
ndi=new NasaDailyFragment(this);
bnf=new BreakingNewsFragment(this);
ft=getFragmentManager().beginTransaction();
ft.add(R.id.focused_view_container,ndi).commit();
public void onTabSelected(Tab tab, FragmentTransaction f)
switch(tab.getPosition())
case 0:
ft=getFragmentManager().beginTransaction();
if(!ndi.isAdded())
ft.replace(R.id.focused_view_container, ndi).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN).commit();
ft.attach(ndi);
getFragmentManager().executePendingTransactions();
break;
case 1:
ft=getFragmentManager().beginTransaction();
ft.detach(ndi);
ft.replace(R.id.focused_view_container, bnf).commit();
getFragmentManager().executePendingTransactions();
break;
【问题讨论】:
【参考方案1】:使用显示和隐藏而不是附加和分离。这是一个示例代码,
private class MyTabListener implements ActionBar.TabListener
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft)
switch (tab.getPosition())
case 0:
if (frag1 == null)
// If not, instantiate and add it to the activity
frag1 = Fragment.instantiate(getApplicationContext(),
FeedsActivity.class.getName());
ft.add(android.R.id.content, frag1, "Feeds");
else
// If it exists, simply attach it in order to show it
ft.show(frag1);
return;
case 1:
if (frag2 == null)
// If not, instantiate and add it to the activity
frag2 = Fragment.instantiate(getApplicationContext(),
ProfileActivity.class.getName());
ft.add(android.R.id.content, frag2, "Profile");
else
// If it exists, simply attach it in order to show it
ft.show(frag2);
return;
case 2:
if (frag3 == null)
// If not, instantiate and add it to the activity
frag3 = Fragment.instantiate(getApplicationContext(),
History.class.getName());
ft.add(android.R.id.content, frag3, "History");
else
// If it exists, simply attach it in order to show it
ft.show(frag3);
return;
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft)
// TODO Auto-generated method stub
if (frag1 != null)
// Detach the fragment, because another one is being attached
switch (tab.getPosition())
case 0:
ft.hide(frag1);
return;
case 1:
ft.hide(frag2);
return;
case 2:
ft.hide(frag3);
return;
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft)
// TODO Auto-generated method stub
【讨论】:
不回答问题,附加和分离有什么用? @BasimSherif 这对我不起作用。我正在使用 ActionBarSherlock。 @BasimSherif 你指的frag1
是什么?
@BasimSherif,不正确 - 分离/附加片段没有被破坏,仅在删除或替换时,这就是分离/附加的全部意义。【参考方案2】:
你的逻辑有问题 - 你替换片段然后再次附加它,或者如果 1 分离然后替换,那是多余的。除了替换你每次切换标签时都会破坏旧片段。 我宁愿走这条路:
public void onTabSelected(Tab tab, FragmentTransaction f)
switch(tab.getPosition())
case 0:
if(ndi.isAdded())
f.detach(bnf);
f.attach(ndi);
else
f.add(R.id.focused_view_container, ndi).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
break;
case 1:
if(bnf.isAdded())
f.detach(ndi);
f.attach(bnf);
else
f.add(R.id.focused_view_container, bnf).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
break;
而且您不必在传递的 FragmentTransaction OnTabSelected 事件上调用 commit。
【讨论】:
【参考方案3】:默认情况下,Fragment
会在您分离然后附加它时重新创建。您可以通过在Fragment
上调用setRetainInstance(true)
来更改此行为:实际实例将保存在内存中,并且在分离-附加循环后不会重新创建。但是Fragment
的 UI 在这两种情况下都会被破坏并在此之后重新创建,因此您需要确保在将Fragment
重新附加到Activity
后使用正确的数据填充视图。希望这会有所帮助。
【讨论】:
错了,setRetainInstance() 方法正在做其他事情 @kreker,“控制是否在 Activity 重新创建过程中保留片段实例” - 意义不同吗? 是的,问题是关于附加 - 分离之间的片段状态,而不是跨活动重新创建以上是关于使用 FragmentTransaction.attach() 和 detach() 时不保留 Fragment ui的主要内容,如果未能解决你的问题,请参考以下文章
在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?
Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)