【问题标题】:Lazy Loading with memory in Android ViewPager在 Android ViewPager 中延迟加载内存
【发布时间】:2013-12-02 03:44:43
【问题描述】:

我有一组用于 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;
    }
}

【问题讨论】:

    标签: android android-viewpager loading lazy-evaluation


    【解决方案1】:

    FragmentStatePagerAdapter 就是你要找的东西

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

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

    【讨论】:

    • 酷。 onSaveInstanceState 似乎有效。但我的 hack 似乎也很有效,除了它没有记录 :-(
    • @SoloPilot 我也使用了相同的 hack,发现它在我测试过的设备上运行良好(中到高端)
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-03
      • 1970-01-01
      • 1970-01-01
      • 2018-07-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多