为什么不分离()上FragmentTransaction工作和remove()呢? [英] Why doesn't detach() work on FragmentTransaction and remove() does?

查看:313
本文介绍了为什么不分离()上FragmentTransaction工作和remove()呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个 TabHost 的标签有关联的片段(每个选项卡一个不同的)。其中每个片段活动的另一个实例里面的片段这是一个有两个状态的登录栏:登录还是不行。

I'm working on a TabHost whose tabs have associated a Fragment (each tab a different one). Each of those Fragments 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆