为什么不分离()上FragmentTransaction工作和remove()呢? [英] Why doesn't detach() work on FragmentTransaction and remove() does?
问题描述
我工作的一个 TabHost
的标签有关联的片段
(每个选项卡一个不同的)。其中每个片段
活动的另一个实例里面的片段
这是一个有两个状态的登录栏:登录还是不行。
I'm working on a TabHost
whose tabs have associated a Fragment
(each tab a different one). Each of those Fragment
s have inside an instance of another Fragment
which is a login bar that has two states: Logged in or not.
已注销例如
登录例如
在布局方面,每个国家都相关的查看
(A 的TextView
对于非已登录在外壳和的LinearLayout
为登录的情况下),因此,如果其中一个是可见
,另外一个为 GONE
。按选项卡的内容,这是其中之一( firsttab.xml
)的code的例子:
In layout terms, each of these states have associated a View
(a TextView
for the non-logged-in case and a LinearLayout
for the logged-in case), so if one of them is VISIBLE
, the other one is GONE
. As per the tab content, this is an example of the code of one of them (firsttab.xml
):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.android.gms.ads"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0000FF"
android:orientation="vertical">
<!-- That's the login bar -->
<fragment
android:id="@+id/firsttab_loginrow"
class="com.mydomain.myproject.LoginRowFragment"
android:tag="1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/firsttab_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:orientation="horizontal">
</LinearLayout>
</LinearLayout>
内分段( com.mydomain.myproject.LoginRowFragment
)的定义是这样的:
<!-- If the user is not logged in -->
<TextView
android:id="@+id/identification_nologin"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textColor="#FFFFFF" />
<!-- if the user is logged in -->
<LinearLayout
android:id="@+id/identification_didlogin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
...
</LinearLayout>
一个通用的模式将是这样的:
A general schema would be something like this:
当我处理由两种)的标签改变事件附加(
ING或分离()
ING记者父片段
(在这种情况下, firsttab.xml
)。 previously到安装/拆卸的父母,我试着分离()
ING登录片段
(内层一个),但它不火的 onDetach()
回调。同样的情况发生时,附加()
ING。奇怪的是,如果我替换 .detach()
与一个.remove()
,它工作得很好。
The problem comes when I'm handling the tab change event by either attach()
ing or detach()
ing the correspondent parent Fragment
(in this case, firsttab.xml
). Previously to attaching/detaching the parent, I try detach()
ing the login Fragment
(the inner one), but it doesn't fire the onDetach()
callback. The same happens when attach()
ing. The weird thing is that if I replace .detach()
with .remove()
, it works just fine.
@Override
public void onTabChanged(final String tag) {
final TabInfo newTab = mTabInfo.get(tag);
if (lastTab != newTab) {
final FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction();
if ((lastTab != null) && (lastTab.getFragment() != null)) {
// This is where it fails detaching. tabInfo is just a structure where I store some data
// about the tabs to handle them. If I use remove() instead of the next detach() on loginFrag,
// the onAttach()/onDetach() callbacks are not called. I'm quite sure everything is ok, loginFrag
// is not null, it's actually the Fragment that should be detached, etc.
final Fragment loginFrag = (Fragment) lastTab.getFragment().getActivity().getSupportFragmentManager().findFragmentById(lastTab.getLoginFragId());
ft.detach(loginFrag);
ft.detach(lastTab.getFragment());
}
if (newTab != null) {
if (newTab.getFragment() == null) {
final TabFragmentInflater tabInf = new TabFragmentInflater();
newTab.setFragment(Fragment.instantiate(this, tabInf.getClass().getName(), newTab.getArgs()));
ft.add(R.id.realtabcontent, newTab.getFragment(), newTab.getTag());
}
else
ft.attach(newTab.getFragment());
}
ft.commit();
this.getSupportFragmentManager().executePendingTransactions();
lastTab = newTab;
}
}
所以现在的问题是:
So the question is the following:
为什么 onAttach()
/ onDetach()
回调未在解雇 LoginRowFragment
时使用类 .attach()
或 .detach()
在他们身上,但如果我用被解雇。新增()
或一个.remove()
分别?
Why onAttach()
/onDetach()
callbacks are not fired in the LoginRowFragment
class when using .attach()
or .detach()
on them, but get fired if I use .add()
or .remove()
respectively?
推荐答案
您不能删除已在您的布局XML文件(设计)被宣布
You cannot remove an instance of a Fragment which has been declared in your layout XML file (by design)
当您使用FragmentTransactions,你操纵包含片段布局ViewGroups。
When you use FragmentTransactions, you're manipulating ViewGroups containing the layout of a Fragment.
当您在布局中声明你的碎片/类,这是View层次结构的一部分,所以你无法将其删除。
When you declare your Fragment/Class in a layout, it's part of the View hierarchy, so you can't remove it.
您可以,但是,添加一个新片段成的布局,因为它会作为一个容器行事。
You can, however, add a New Fragment into that layout, because it will act as a container.
尝试从改变你的布局:
<fragment
android:id="@+id/firsttab_loginrow"
class="com.mydomain.myproject.LoginRowFragment"
android:tag="1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
到
<FrameLayout
android:id="@+id/firsttab_loginrow"
android:tag="1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
和创建一个 FragmentTransaction
添加/根据你想要做什么替换/显示/隐藏。
And create a FragmentTransaction
to add/replace/show/hide according to what you want to do.
这篇关于为什么不分离()上FragmentTransaction工作和remove()呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!