fragmentContainer是片段的唯一标识符?

时间:2016-01-22 04:15:28

标签: android android-fragments

我对片段管理器和片段感到困惑。在大书呆子牧场的“Android编程”一书中,他们在MainActivity中实例化了一个片段。

FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);

if (fragment == null) {
    fragment = new CrimeFragment();
    fm.beginTransaction()
        .add(R.id.fragmentContainer, fragment)
        .commit();
} 

在第二行中,他们发现片段不是通过片段的ID,而是通过fragmentContainer的ID。 FragmentContainer只是一个简单的布局。该书说“[容器视图ID]被用作FragmentManager列表中片段的唯一标识符。

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>

在另一个页面上,当编写这个fragmentContainer时,他们写道“你可以并且将使用这个相同的布局来托管其他片段。”

如果此布局可以托管其他片段,那么如何将此布局用作FragmentManager列表中片段的唯一标识符?他们为什么不这样做

fm.findFragmentById(R.id.[some fragment id here]) 

而是使用可以托管其他片段的片段容器的Id?

2 个答案:

答案 0 :(得分:1)

  

他们发现片段不是通过片段的ID,而是通过ID的ID   fragmentContainer。

很酷的是Fragment ID和Fragment Container ID是一回事!更新代码以添加一些日志记录语句:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_crime);

    FragmentManager fm = getSupportFragmentManager();
    Fragment fragment = fm.findFragmentById(R.id.fragment_container);

    if (fragment != null) {
        Log.d(TAG, "fragment id: " + fragment.getId());
    }

    View fragmentContainer = findViewById(R.id.fragment_container);
    Log.d(TAG, "fragment container id: " + fragmentContainer.getId());

    if (fragment == null) {
        fragment = new CrimeFragment();
        fm.beginTransaction()
                .add(R.id.fragment_container, fragment)
                .commit();
    }
}

然后运行应用程序并旋转设备:

CrimeActivity: fragment container id: 2131296335
DEVICE ROTATION
CrimeActivity: fragment id: 2131296335
CrimeActivity: fragment container id: 2131296335

显然,你的身份证会与我的身份证明不同。

创建FragmentTransaction

fm.beginTransaction().add(R.id.fragmentContainer, fragment)

FragmentManager将使用ID作为两者一种方法,从正在管理的片段列表中识别此片段,作为要显示的视图层次结构中的位置片段。

  

在另一个页面上,当编写这个fragmentContainer时,他们会写   &#34;您可以并将使用相同的布局来托管其他片段。&#34;

     

如果此布局可以托管其他片段,那么如何使用此布局   作为FragmentManager列表中片段的唯一标识符?

应该澄清最后一句话以便阅读

&#34;您可以并将使用相同的布局来托管其他片段,方法是将当前片段替换为不同的片段。&#34;

只有一个片段具有该ID,并且视图层次结构中只有一个点具有该ID。跳转到代码清单17.8(在第二版中)以查看替换示例。

if (findViewById(R.id.detail_fragment_container) == null) {
    Intent intent = CrimePagerActivity.newIntent(this, crime.getId());
    startActivity(intent);
} else {
    Fragment newDetail = CrimeFragment.newInstance(crime.getId());
    getSupportFragmentManager().beginTransaction()
            .replace(R.id.detail_fragment_container, newDetail)
            .commit();
}

使用throw方式替换调用,无论片段当前位于detail_fragment_container并插入newDetail片段,将其ID设置为R.id.detail_fragment_container

为什么不使用标签?

一条评论建议:

  

我会使用标签:.add(R.id.fragmentContainer,fragment,&#34; MY TAG&#34;)和   然后:findFragmentById(&#34; MY TAG&#34;)

这并不能直接解决问题。现在,您有两种方法可以识别片段:它的标记及其ID(片段仍将通过将其添加到R.id.fragment_container的事实来获得ID)。

有两种识别片段的方法,作为开发人员,您可以自行跟踪显示的内容。这个片段是什么(它是什么标签)以及它在哪里显示(它的ID是什么)?

答案 1 :(得分:0)

  

查找由给定id标识的片段   在XML中膨胀或在事务中添加时作为容器ID。   这首先搜索当前添加到的片段   经理的活动;如果没有找到这样的片段,那么所有片段   当前在与此ID相关联的后台堆栈上进行搜索。

这是findFragmentById( )的文档。如果片段是使用fragment标记从XML中膨胀的,那么它将完全按照您的说法执行。如果它是通过使用事务动态添加的,那么它将查找具有关联容器ID的片段。