如何妥善处理屏幕旋转与ViewPager和嵌套的片段? [英] How to properly handle screen rotation with a ViewPager and nested fragments?

查看:194
本文介绍了如何妥善处理屏幕旋转与ViewPager和嵌套的片段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个活动,其中包含一个片段。此片段布局由视图寻呼机几个片段(二,实际上)。

I've got this activity, which holds a fragment. This fragment layout consists of a view pager with several fragments (two, actually).

在创建视图寻呼机,创建它的适配器, 的getItem 被称为创建和我的子片段。太好了。

When the view pager is created, its adapter is created, getItem gets called and my sub fragments are created. Great.

现在,当我旋转屏幕,该框架处理片段再创作,适配器在我的的onCreate 从主片段,但 <再次创造code>的getItem 不会被调用,所以我的适配器持有错误的引用(实际上归零),而不是两个片段。

Now when I rotate the screen, the framework handles the fragment re-creation, the adapter is created again in my onCreate from the main fragment, but getItem never gets called, so my adapter holds wrong references (actually nulls) instead of the two fragments.

我所发现的是,该片段的经理(即子片段经理)含有片段名为 mActive 的数组,这当然是不能从$访问C $℃。但是有这个 getFragment 方法:

What I have found is that the fragment manager (that is, the child fragment manager) contains an array of fragments called mActive, which is of course not accessible from code. However there's this getFragment method:

@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;
}

<一个href="https://github.com/android/platform_frameworks_support/commit/37e2defcdb38fee7acec85747fb8afdcb0fdca7f">I不会评论错字:)
这是我为了更新引用到我的片段,在我的适配器构造函数来实现破解:

I won't comment the typo :)
This is the hack I have implemented in order to update the references to my fragments, in my adapter constructor:

// 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
}

我不感到自豪。这工作,但它的丑陋。什么是屏幕旋转之后有一个有效的适配器的实际方法是什么?

I am not proud. This works, but it's ugly. What's the actual way of having a valid adapter after a screen rotation?

PS:这里的全code

推荐答案

我有同样的问题 - 我假设你继承FragmentPagerAdapter您的寻呼机适配器(如getItem()时是特定于FragmentPagerAdapter)

I had the same issue - I assume you're subclassing FragmentPagerAdapter for your pager adapter (as getItem() is specific to FragmentPagerAdapter).

我的解决办法是,而不是继承PagerAdapter和处理片段创建/删除自己(重新实现一些FragmentPagerAdapter code):

My solution was to instead subclass PagerAdapter and handle the fragment creation/deletion yourself (reimplementing some of the FragmentPagerAdapter code):

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];
    }
}

希望这有助于。

Hope this helps.

这篇关于如何妥善处理屏幕旋转与ViewPager和嵌套的片段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆