我的应用程序中存在架构问题。我使用了导航抽屉和几个片段的一个活动。现在,
假设我有两个片段A和B.导航结构有点:
A
A1
A2
乙
B1
B2
其中A1,A2是A型片段,B1,B2是B型片段。相同类型的片段之间的唯一区别,例如。 A1,A2是数据。
我的第一个方法:
每当用户点击A1,A2,B1,B2时。我只是创建该类型的新实例并替换片段。
Fragment fragment =A.newInstance();
private void replaceFragment(Fragment fragment) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment).commit();
mDrawerLayout.closeDrawer(rlDrawer);
}
注意:我不想将它们添加到后台。
后来我意识到这种方法效率很低,因为每次它都会在该片段上创建一个新实例,即使它们属于同一类型。正如我之前所说,差异仅在于数据。所以,我转向下一个方法
第二种方法:
现在我的活动有片段A和B的数据成员(引用)。现在我将检查它是否为空,然后创建一个新实例,否则只需更改数据:
if (A == null) {
a = A.newInstance();
} else {
((A) a).changeData();
}
replaceFragment(a);
这种方法的问题在于,当我从片段A1切换到B1时,A1片段被破坏,但其参考仍保留活动。现在,当我从B1切换回A1时,它不会创建一个新实例,因为您可以在上面的代码中看到,但同时onCreate()方法在Fragment A上被调用。
如果在片段上调用onDestroy(),我是否应该从活动中删除引用?
我的第二种方法是否正确?
有没有更好的方法呢?
提前致谢。
答案 0 :(得分:1)
我会略微修改你的第一种方法。
为片段使用字符串标记。
当您替换片段时,请使用带有三个参数的replace
方法,例如:
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment, TAG_A1).commit();
其中TAG_A1
是唯一的String标记。
您可以使用findFragmentByTag中的FragmentManager方法检查片段是否已在替换之前创建。
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fragmentA1 = fragmentManager.findFragmentByTag(TAG_A1);
if(fragment == null) {
fragment = A.newInstance();
}
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment, TAG_A1).commit();