为什么FragmentManager.FindFragmentById可以用于FrameLayout?

时间:2016-07-18 14:35:37

标签: c# android android-fragments xamarin xamarin.android

我完全不理解Xamarin示例中有关在此使用Tab https://developer.xamarin.com/samples/HelloTabsICS

的一段代码

据我所知,FragmentManager.FindFragmentById应该返回Fragment,而id当然应该是Fragment文件夹下的XML文件中定义的layout。但是上面链接中的代码对我来说有些奇怪,这里有一个布局xml文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent">
   <FrameLayout
      android:id="@+id/fragmentContainer"
      android:layout_width="match_parent"
      android:layout_height="0dip"
      android:layout_weight="1" />
</LinearLayout>

以下代码(在示例演示中)可以从ID为Fragment的{​​{1}}中找到fragmentContainer?这完全没有任何意义,这是代码:

FrameLayout

为什么可以使用 var fragment = this.FragmentManager.FindFragmentById(Resource.Id.fragmentContainer); if (fragment != null) e.FragmentTransaction.Remove(fragment); 的ID来查找FrameLayout的实例?那时候真的很混乱。

我对Xamarin.Android以及Android编程(刚刚经历了5天)相当新。所以请帮我解释一下这个奇怪的事情。

非常感谢!

1 个答案:

答案 0 :(得分:0)

这是因为FrameLayout包含一个Fragment,您可以通过编程实现它。

假设你有一个片段,比如FirstFrag.cs​​,无论用什么UI元素做什么都包含在内。您可以在FrameLayout中实例化此片段:

FragmentTransaction tx = FragmentManager.BeginTransaction ();
tx.Replace (Resource.Id.fragmentContainer, new FirstFrag ());
tx.Commit(); //Where fragmentContainer is your FrameLayout.
//Also note that tx.Replace is acting like tx.Add if there is no fragment.

然后,在FrameLayout上使用FindFragmentById,您将能够将FirstFrag包含在其中作为Fragment对象。更好,你可以直接把它作为FirstFrag:

FirstFrag frag = FragmentManager.FindFragmentById<FirstFrag>(Resource.id.fragmentContainer);

FrameLayout只是充当片段的容器。您可以使用任何布局,具体取决于您希望如何显示片段内容。

现在让我们假设您有第二个片段,名为SecondFrag.cs​​。如果使用tx.Add()将其添加到容器中,它将与第一个堆叠到容器中。如果您使用替换,则将删除第一个。 但是在同一个容器中有两个片段似乎是个坏主意。理想情况下,您希望每个容器都有一个片段。

如果你真的需要在容器中放置两个片段,你可以在片段中添加一个Tag:

FragmentTransaction tx = FragmentManager.BeginTransaction();
tx.Add(Resource.id.fragmentContainer, new SecondTag(), "YourTag");
tx.Commit();

然后,要从容器中找到精确的片段,您可以这样做:

var frag = FragmentManager.FindFragmentByTag("YourTag");

但同样,这不是一个好主意。每个容器一个片段是要走的路。

注意:我有很奇怪的结果试图在提交后立即从容器中获取片段。它始终给我以前的容器内容。我想这是计划以这种方式工作的,但是一旦调用它的方法结束,似乎真的应用了提交。

希望我已经足够清楚,随时可以询问更多细节!