在Android ViewPager中使用内存进行延迟加载

时间:2013-11-18 20:25:04

标签: android android-viewpager loading lazy-evaluation

我在ViewPager中使用了一组可垂直滚动的页面。我需要保留每个ScrollView的状态以保留滚动位置。将mPager.setOffscreenPageLimit()设置为最大页数可正常工作,但加载时间过长。我需要的是ViewPager在需要时懒惰地调用onCreateView(),但不会销毁任何已创建的视图。一个似乎正常工作的解决方案是覆盖FragmentPagerAdapter.destroyItem()并且不执行任何操作,不要调用super。

问题:这会导致任何问题吗?有一个更好的方法吗? TIA。

static ArrayList<ScreenSlidePageFragment> fragments;

public void onCreate(Bundle savedInstanceState) {
    ...
    fragments = new ArrayList<ScreenSlidePageFragment>();
    for (int i = 0; i < numScrollViews; ++i) {
        ScreenSlidePageFragment fragment = new ScreenSlidePageFragment();
        fragment.initialize(Integer.toString(i));
        fragments.add(fragment);
    }

    ViewPager mPager = (ViewPager) findViewById(R.id.viewpager);
    PagerAdapter mPagerAdapter = new PagerAdapter(super.getSupportFragmentManager());
    mPager.setAdapter(mPagerAdapter);
    // adding the following line makes things slow
    //mPager.setOffscreenPageLimit(fragments.size());
    ...
}

public static class PagerAdapter extends FragmentPagerAdapter {
    public PagerAdapter(FragmentManager fm) {    // Must define an explicit constructor
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        System.out.println("PagerAdapter: getItem "+position);
        return fragments.get(position);
    }

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

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        System.out.println("PagerAdapter: destroyItem "+position);
        // do not call super.destroyItem(container, position, object)
    }
}

public static class ScreenSlidePageFragment extends Fragment {
    private String mKey;

    public ScreenSlidePageFragment() {
        System.out.println("ScreenSlidePageFragment: constructor ");
    }

    public void initialize(String key) {
        mKey = key;        // instead of args Bundle BS
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // Inflate the layout containing a title and body text.
        ViewGroup rootView = (ViewGroup) inflater
                .inflate(R.layout.fragment_screen_slide_page, container, false);

        TextView textView = (TextView) rootView.findViewById(android.R.id.text1);
        textView.setText("Key "+mKey);

        textView = (TextView) rootView.findViewById(android.R.id.text2);
        textView.setText("blah blah");
        System.out.println("ScreenSlidePageFragment: onCreateView: "+mKey);
        return rootView;
    }
}

2 个答案:

答案 0 :(得分:1)

你正在寻找

FragmentStatePagerAdapter

普通的FragmentPagerAdapter不会重新创建完整的Fragment,而只会释放视图以节省内存。如果你沿着viewpager滑动,FragmentStatePagerAdapter将破坏完整的Fragement。

因此,在您的情况下,您可以使用FragmentStatePagerAdapter并覆盖存储当前滚动位置的片段onSaveInstanceState(Bundle outState)。然后在onCreateView(Bundle savedInstanceState)中恢复滚动位置。

答案 1 :(得分:0)

嵌入式打印语句的输出表明,对于同一个ScrollView页面,不会重复调用onCreateView()。