android - 如何使用 ViewPager 和嵌套 fragment 正确处理屏幕旋转?

标签 android android-fragments android-viewpager android-adapter

我有这个 Activity ,其中包含一个 fragment 。这个 fragment 布局由一个带有多个 fragment (实际上是两个)的 View 分页器组成。

创建 View 分页器时,会创建其适配器,调用 getItem 并创建我的子 fragment 。太好了。

现在,当我旋转屏幕时,框架会处理 fragment 重新创建,适配器会在我的 onCreate 中从主 fragment 再次创建,但是 getItem 永远不会被调用,所以我的适配器持有错误的引用(实际上是空值)而不是两个 fragment 。

我发现 fragment 管理器(即子 fragment 管理器)包含一个名为mActive的 fragment 数组,当然不能从代码中访问。但是有这个 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;
}

I won't comment the typo :)
这是我为了更新对我的 fragment 的引用而在我的适配器构造函数中实现的 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:这里是 full code

最佳答案

我遇到了同样的问题 - 我假设您正在为您的寻呼机适配器子类化 FragmentPagerAdapter(因为 getItem() 特定于 FragmentPagerAdapter )。

我的解决方案是改为子类 PagerAdapter 并自己处理 fragment 创建/删除(重新实现一些 FragmentPagerAdapter 代码):

public class ListPagerAdapter extends PagerAdapter {
    FragmentManager fragmentManager;
    Fragment[] fragments;

    public ListPagerAdapter(FragmentManager fm){
        fragmentManager = fm;
        fragments = new Fragment[5];
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        assert(0 <= position && position < fragments.length);
        FragmentTransaction trans = fragmentManager.beginTransaction();
        trans.remove(fragments[position]);
        trans.commit();
        fragments[position] = null;
}

    @Override
    public Fragment instantiateItem(ViewGroup container, int position){
        Fragment fragment = getItem(position);
        FragmentTransaction trans = fragmentManager.beginTransaction();
        trans.add(container.getId(),fragment,"fragment:"+position);
        trans.commit();
        return fragment;
    }

    @Override
    public int getCount() {
        return fragments.length;
    }

    @Override
    public boolean isViewFromObject(View view, Object fragment) {
        return ((Fragment) fragment).getView() == view;
    }

    public Fragment getItem(int position){
        assert(0 <= position && position < fragments.length);
        if(fragments[position] == null){
            fragments[position] = ; //make your fragment here
        }
        return fragments[position];
    }
}

希望这会有所帮助。

关于android - 如何使用 ViewPager 和嵌套 fragment 正确处理屏幕旋转?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19393076/

相关文章:

android - 基于android上用户区域设置的日期格式

android - Activity 结束时关闭对话框

安卓 SearchView OnFocusChangeListener : onFocusChange is not called at all

java - Android ViewPager 不显示我的所有布局元素

android - 嵌套的 ViewPager 在 onBackPressed() 上空白内容

android - CollapsingToolbarLayout 在 4.4 设备上崩溃 (java.lang.IllegalArgumentException : radius must be > 0)

java - 类似于 Toast 的通知,但持续时间更长

android - 单击重叠的 UI 元素

Android Fragment Transition - 动画期间避免GC

android - 如何禁用 ViewGroup 的所有子项上的所有触摸事件?