我有一个活动(Activity),其中包含一个碎片(Fragment)。这个碎片布局由一个带有几个碎片(实际上只有两个)的视图翻页器(ViewPager)组成。
当视图翻页器被创建时,它的适配器(Adapter)也会被创建,getItem
方法被调用,我的子碎片(Sub Fragments)就会被创建。这很棒。
现在,当我旋转屏幕时,框架会处理碎片的重新创建,在主碎片中的 onCreate
中会再次创建适配器,但是 getItem
永远不会被调用,因此我的适配器存储了错误的引用(实际上是 null),而不是这两个碎片。
我发现的是,碎片管理器(即子碎片管理器)包含一个名为 mActive
的碎片数组,当然这个数组无法从代码中访问。但是有这个 getFragment
方法:
@Override
public Fragment getFragment(Bundle bundle, String key) {
int index = bundle.getInt(key, -1);
if (index == -1) {
return null;
}
if (index >= mActive.size()) {
throwException(new IllegalStateException("Fragement no longer exists for key "
+ key + ": index " + index));
}
Fragment f = mActive.get(index);
if (f == null) {
throwException(new IllegalStateException("Fragement no longer exists for key "
+ key + ": index " + index));
}
return f;
}
我不会评论这个错别字 :)
这是我在适配器构造函数中实现更新片段引用的hack:
// fm holds a reference to a FragmentManager
Bundle hack = new Bundle();
try {
for (int i = 0; i < mFragments.length; i++) {
hack.putInt("hack", i);
mFragments[i] = fm.getFragment(hack, "hack");
}
} catch (Exception e) {
// No need to fail here, likely because it's the first creation and mActive is empty
}
我不感到骄傲。这个方法可行,但很丑陋。在屏幕旋转后,有什么实际的方法可以获得一个有效的适配器?
PS:这里是完整代码