资讯专栏INFORMATION COLUMN

ViewPager原理分析(一)

付伦 / 2351人阅读

摘要:当,调用上面的实现主要在中和旧的的比较,如果不同,重新获取遍历之前的,在范围之内的没有的添加,在范围之外的有的删除遍历之后的,在范围之内的没有的添加,在范围之外的有的删除是一个在中由程序员调用第一步第二步第三步

当MotionEvent.ACTION_UP,调用populate
上面的实现主要在ViewPager.populte(curItemIndex)中;

curItemIndex和旧的mCurItem的index比较,如果不同,重新获取mCurItem;

遍历mCurItem之前的Item, 在范围之内的没有的添加,在范围之外的有的删除;

遍历mCurItem之后的Item, 在范围之内的没有的添加,在范围之外的有的删除;

ViewPager是一个ViewGroup, addView/removeView 在destroyItem,instantiateItem中由程序员调用;

ViewPager.java:

        //第一步
        int curIndex = -1;
        ItemInfo curItem = null;
        for (curIndex = 0; curIndex < mItems.size(); curIndex++) {
            final ItemInfo ii = mItems.get(curIndex);
            if (ii.position >= mCurItem) {
                if (ii.position == mCurItem) curItem = ii;
                break;
            }
        }

        if (curItem == null && N > 0) {
            curItem = addNewItem(mCurItem, curIndex);
        }
        ... ...
        //第二步,第三步
        if (curItem != null) {
            float extraWidthLeft = 0.f;
            int itemIndex = curIndex - 1;
            ItemInfo ii = itemIndex >= 0 ? mItems.get(itemIndex) : null;
            final int clientWidth = getClientWidth();
            final float leftWidthNeeded = clientWidth <= 0 ? 0 :
                    2.f - curItem.widthFactor + (float) getPaddingLeft() / (float) clientWidth;
            for (int pos = mCurItem - 1; pos >= 0; pos--) {
                if (extraWidthLeft >= leftWidthNeeded && pos < startPos) {
                    if (ii == null) {
                        break;
                    }
                    if (pos == ii.position && !ii.scrolling) {
                        mItems.remove(itemIndex);
                        mAdapter.destroyItem(this, pos, ii.object);
                        if (DEBUG) {
                            Log.i(TAG, "populate() - destroyItem() with pos: " + pos
                                    + " view: " + ((View) ii.object));
                        }
                        itemIndex--;
                        curIndex--;
                        ii = itemIndex >= 0 ? mItems.get(itemIndex) : null;
                    }
                } else if (ii != null && pos == ii.position) {
                    extraWidthLeft += ii.widthFactor;
                    itemIndex--;
                    ii = itemIndex >= 0 ? mItems.get(itemIndex) : null;
                } else {
                    ii = addNewItem(pos, itemIndex + 1);
                    extraWidthLeft += ii.widthFactor;
                    curIndex++;
                    ii = itemIndex >= 0 ? mItems.get(itemIndex) : null;
                }
            }

            float extraWidthRight = curItem.widthFactor;
            itemIndex = curIndex + 1;
            if (extraWidthRight < 2.f) {
                ii = itemIndex < mItems.size() ? mItems.get(itemIndex) : null;
                final float rightWidthNeeded = clientWidth <= 0 ? 0 :
                        (float) getPaddingRight() / (float) clientWidth + 2.f;
                for (int pos = mCurItem + 1; pos < N; pos++) {
                    if (extraWidthRight >= rightWidthNeeded && pos > endPos) {
                        if (ii == null) {
                            break;
                        }
                        if (pos == ii.position && !ii.scrolling) {
                            mItems.remove(itemIndex);
                            mAdapter.destroyItem(this, pos, ii.object);
                            if (DEBUG) {
                                Log.i(TAG, "populate() - destroyItem() with pos: " + pos
                                        + " view: " + ((View) ii.object));
                            }
                            ii = itemIndex < mItems.size() ? mItems.get(itemIndex) : null;
                        }
                    } else if (ii != null && pos == ii.position) {
                        extraWidthRight += ii.widthFactor;
                        itemIndex++;
                        ii = itemIndex < mItems.size() ? mItems.get(itemIndex) : null;
                    } else {
                        ii = addNewItem(pos, itemIndex);
                        itemIndex++;
                        extraWidthRight += ii.widthFactor;
                        ii = itemIndex < mItems.size() ? mItems.get(itemIndex) : null;
                    }
                }
            }

            calculatePageOffsets(curItem, curIndex, oldCurInfo);
        }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/70779.html

相关文章

  • 反射改变TabLayout属性

    摘要:第二种在原有基础上通过继承控件,重写其中几个方法,并且通过反射来修改部分属性,也能达到第一种方案效果。因此这里需要用反射替换成自己的滑动监听,然后在的监听类中的方法,改变的颜色。通过反射找到源码中成员变量,然后设置暴力访问权限。 目录介绍 01.遇到的实际需求分析 02.原生TabLayout局限 03.TabLayout源码解析 3.1 Tab选项卡如何实现 3.2 滑动切换T...

    GeekGhc 评论0 收藏0

发表评论

0条评论

付伦

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<