我正在开发 TabHost
其选项卡关联了 Fragment
(每个选项卡不同)。其中每一个 Fragment
s 内部有另一个 Fragment
的实例这是一个登录栏,有两种状态:登录或未登录。
注销示例
登录示例
在布局方面,每个状态都关联了 View
(TextView
表示未登录的情况,LinearLayout
表示登录的情况),因此如果其中之一是 VISIBLE
,另一个是GONE
。根据选项卡内容,这是其中之一的代码示例 ( 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>
内部 fragment ( 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>
一般架构如下所示:
当我通过 attach()
处理选项卡更改事件时,问题就出现了。 ing 或 detach()
联系通讯家长Fragment
(在本例中为 firsttab.xml
)。在附加/分离父级之前,我尝试 detach()
登录Fragment
(内部的),但它不会触发 onDetach()
打回来。当 attach()
时也会发生同样的情况ing。奇怪的是,如果我替换 .detach()
与 .remove()
,它工作得很好。
@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;
}
}
所以问题如下:
为什么 onAttach()
/onDetach()
LoginRowFragment
中不会触发回调使用 .attach()
时的类或.detach()
对他们来说,但如果我使用 .add()
就会被解雇或.remove()
分别?
最佳答案
您无法删除已在布局 XML 文件中声明的 Fragment 实例(按设计)
当您使用 FragmentTransactions 时,您正在操作包含 Fragment 布局的 ViewGroup。
当您在布局中声明 fragment/类时,它是 View 层次结构的一部分,因此您无法删除它。
但是,您可以将新 fragment 添加到该布局中,因为它将充当容器。
尝试更改您的布局:
<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
来根据您想要执行的操作添加/替换/显示/隐藏。
关于android - 为什么 detach() 对 FragmentTransaction 不起作用,而 remove() 却可以?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22408600/