博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ViewPager源码分析(一) 创建与销毁Item
阅读量:6305 次
发布时间:2019-06-22

本文共 7252 字,大约阅读时间需要 24 分钟。

一。属性

1.setPageMargin
2.setOffscreenPageLimit

二。

1.什么时候调用PagerAdapter.instantiateItem

//在populate中,遍历mCurItem之前的, addNewItem满足这个条件的pos == ii.position && !ii.scrolling

遍历mCurItem之后的, addNewItem满足这个条件的pos == ii.position && !ii.scrolling
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;    }
void populate(int newCurrentItem) {        ... ...        // Locate the currently focused item or add it if needed.        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);        }        ... ...        // Fill 3x the available width or up to the number of offscreen        // pages requested to either side, whichever is larger.        // If we have no current item we have no work to do.        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;                }            }            ... ...             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;                    }                }            }    }

2.什么时候调用PagerAdapter.destroyItem

//在dataSetChanged中遍历mItems,利用PagerAdapter.getItemPosition() destroyItem pos
//在populate中,遍历mCurItem之前的, destroyItem满足这个条件的pos == ii.position && !ii.scrolling

遍历mCurItem之后的, destroyItem满足这个条件的pos == ii.position && !ii.scrolling
void dataSetChanged() {      ... ...       for (int i = 0; i < mItems.size(); i++) {            final ItemInfo ii = mItems.get(i);            final int newPos = mAdapter.getItemPosition(ii.object);            if (newPos == PagerAdapter.POSITION_UNCHANGED) {                continue;            }            if (newPos == PagerAdapter.POSITION_NONE) {                mItems.remove(i);                i--;                if (!isUpdating) {                    mAdapter.startUpdate(this);                    isUpdating = true;                }                mAdapter.destroyItem(this, ii.position, ii.object);                needPopulate = true;                if (mCurItem == ii.position) {                    // Keep the current item in the valid range                    newCurrItem = Math.max(0, Math.min(mCurItem, adapterCount - 1));                    needPopulate = true;                }                continue;          }          ... ... }

原理:

图片描述

3.什么时候调用populate(item)

item是curItem

void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity) {        ... ...        if (mFirstLayout) {            // We don't have any idea how big we are yet and shouldn't have any pages either.            // Just set things up and let the pending layout handle things.            mCurItem = item;            if (dispatchSelected) {                dispatchOnPageSelected(item);            }            requestLayout();        } else {            populate(item);            scrollToItem(item, smoothScroll, velocity, dispatchSelected);        }    }

在onRestoreInstanceState,

onTouchEvent(MotionEvent ev) MotionEvent.ACTION_UP mIsBeingDragged==true时,
程序员调用setCurrentItem,setAdapter, endFakeDrag时
dataSetChanged,

private class PagerObserver extends DataSetObserver {        PagerObserver() {        }        @Override        public void onChanged() {            dataSetChanged();        }        @Override        public void onInvalidated() {            dataSetChanged();        }    }

PagerAdapter.java:

public void notifyDataSetChanged() {        synchronized (this) {            if (mViewPagerObserver != null) {                mViewPagerObserver.onChanged();            }        }        mObservable.notifyChanged();    }

也就说除非用户自己调用setCurrentItem,setAdapter, endFakeDrag,PagerAdapter.notifyDataSetChanged ,只有在ACTION_UP时,才会调用populate(item)

转载地址:http://foixa.baihongyu.com/

你可能感兴趣的文章
采集音频和摄像头视频并实时H264编码及AAC编码
查看>>
3星|《三联生活周刊》2017年39期:英国皇家助产士学会于2017年5月悄悄修改了政策,不再鼓励孕妇自然分娩了...
查看>>
linux查看命令是由哪个软件包提供的
查看>>
高级Linux工程师常用软件清单
查看>>
堆排序算法
查看>>
folders.cgi占用系统大量资源
查看>>
路由器ospf动态路由配置
查看>>
zabbix监控安装与配置
查看>>
python 异常
查看>>
last_insert_id()获取mysql最后一条记录ID
查看>>
可执行程序找不到lib库地址的处理方法
查看>>
bash数组
查看>>
Richard M. Stallman 给《自由开源软件本地化》写的前言
查看>>
oracle数据库密码过期报错
查看>>
修改mysql数据库的默认编码方式 .
查看>>
zip
查看>>
How to recover from root.sh on 11.2 Grid Infrastructure Failed
查看>>
rhel6下安装配置Squid过程
查看>>
《树莓派开发实战(第2版)》——1.1 选择树莓派型号
查看>>
在 Linux 下使用 fdisk 扩展分区容量
查看>>