我对片段管理器和片段感到困惑。在大书呆子牧场的“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?
答案 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的片段。