平方X

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 4039|回复: 0

[Android] viewpager和fragment的懒加载。

[复制链接]

414

主题

709

帖子

3611

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3611
QQ
发表于 2016-5-12 11:07:04 | 显示全部楼层 |阅读模式
以这个为例
http://www.2cto.com/kf/201501/368954.html
①BaseFragment 中重写setUserVisibleHint()设置标记,在加载时判断。
//关闭预加载,默认一次只加载一个Fragment
②mViewPager.setOffscreenPageLimit(1);
但是,这个注释是不正确的。具体打log可以发现,加载0时会预加载1,加载2时会加载1和3.
我们看源码
1,首先是方法实现

    /**
     * Set the number of pages that should be retained to either side of the
     * current page in the view hierarchy in an idle state. Pages beyond this
     * limit will be recreated from the adapter when needed.
     *
     * <p>This is offered as an optimization. If you know in advance the number
     * of pages you will need to support or have lazy-loading mechanisms in place
     * on your pages, tweaking this setting can have benefits in perceived smoothness
     * of paging animations and interaction. If you have a small number of pages (3-4)
     * that you can keep active all at once, less time will be spent in layout for
     * newly created view subtrees as the user pages back and forth.</p>
     *
     * <p>You should keep this limit low, especially if your pages have complex layouts.
     * This setting defaults to 1.</p>
     *
     * @param limit How many pages will be kept offscreen in an idle state.
     */
    public void setOffscreenPageLimit(int limit) {
        if (limit < DEFAULT_OFFSCREEN_PAGES) {
            Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to " +
                    DEFAULT_OFFSCREEN_PAGES);
            limit = DEFAULT_OFFSCREEN_PAGES;
        }
        if (limit != mOffscreenPageLimit) {
            mOffscreenPageLimit = limit;
            populate();
        }
    }

2,这个mOffscreenPageLimit,在 void populate(int newCurrentItem)用到,用来计算start和end,然后根据start和end分别做了循环(具体参见源代码)

        final int pageLimit = mOffscreenPageLimit;
        final int startPos = Math.max(0, mCurItem - pageLimit);
        final int N = mAdapter.getCount();
        final int endPos = Math.min(N-1, mCurItem + pageLimit);

最后在循环中,如果为null的,执行
                    ii = addNewItem(pos, itemIndex + 1);
3,在
ItemInfo addNewItem(int position, int index) {
        ItemInfo ii = new ItemInfo();
        ii.position = position;
        ii.object = mAdapter.instantiateItem(this, position);
        ii.widthFactor = mAdapter.getPageWidth(position);
        if (index < 0 || index >= mItems.size()) {
            mItems.add(ii);
        } else {
            mItems.add(index, ii);
        }
        return ii;
    }
4,在adapter中,FragmentPagerAdapter中

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }

        final long itemId = getItemId(position);

        // Do we already have this fragment?
        String name = makeFragmentName(container.getId(), itemId);
        Fragment fragment = mFragmentManager.findFragmentByTag(name);
        if (fragment != null) {
            if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
            mCurTransaction.attach(fragment);
        } else {
            fragment = getItem(position);
            if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
            mCurTransaction.add(container.getId(), fragment,
                    makeFragmentName(container.getId(), itemId));
        }
        if (fragment != mCurrentPrimaryItem) {
            fragment.setMenuVisibility(false);
            fragment.setUserVisibleHint(false);
        }

        return fragment;
    }
5,所以我们看到 fragment = getItem(position);
整理一下,在getItem中加载的fragment,依次被FragmentPagerAdapter中的instantiateItem()方法,ViewPager中的addNewItem方法、populate()方法调用。
调用时根据mOffscreenPageLimit预加载,而这个最小是1,所以肯定会预加载。
在最上面的例子中,已经new了,只是没有初始化等。
所以如果我们要想设置为0。只能自定义一个,然后改为0就好了。
我是平方X~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|平方X ( 冀ICP备14018164号 )

GMT+8, 2024-9-8 10:04 , Processed in 0.118971 second(s), 22 queries .

技术支持:Powered by Discuz!X3.4  © 2001-2013 Comsenz Inc.

版权所有:Copyright © 2014-2018 平方X www.pingfangx.com All rights reserved.

快速回复 返回顶部 返回列表