ViewPager不为人知的秘密

ViewPager切换Page之修改默认滑动偏移量

把ViewPager源码复制一份,修改determineTargetPage方法,determineTargetPage这个方法就是计算接下来要滑到哪一页。这个方法调用是在MotionEvent.ACTION_UP这个事件下,先说下参数意思:

currentPage:当前ViewPager显示的页面
pageOffset:用户滑动的页面偏移量
velocity: 滑动速率
deltaX: X方向移动的距离

/** 最小可切换Page的偏移量**/ 

private float minPageOffset = 0.6f; 

public void setMinPageOffset(float pageOffset){ 

    minPageOffset = pageOffset; 

} 

private int determineTargetPage(int currentPage, float pageOffset, int velocity, int deltaX) { 

    int targetPage; 

    if (Math.abs(deltaX) > mFlingDistance && Math.abs(velocity) > mMinimumVelocity) { 

        targetPage = velocity > 0 ? currentPage : currentPage + 1; 

    } else { 

        final float truncator = currentPage >= mCurItem ? 1.0f - minPageOffset : minPageOffset; 

        targetPage = (int) (currentPage + pageOffset + truncator); 

    } 



    if (mItems.size() > 0) { 

        final ItemInfo firstItem = mItems.get(0); 

        final ItemInfo lastItem = mItems.get(mItems.size() - 1); 



        // Only let the user target pages we have items for 

        targetPage = Math.max(firstItem.position, Math.min(targetPage, lastItem.position)); 

    } 



    return targetPage; 

} 

ViewPager设置子View是否能滑动

改写 ViewPager源码 canScroll(View v, boolean checkV, int dx, int x, int y) 方法返回值

ViewPager之垂直方向的ViewPager以及transformer

https://github.com/kaelaela/VerticalViewPager

ViewPager强制刷新UI

ViewPager不能动态刷新UI的原因主要是因为PagerAdapter中调用notifyDataSetChanged是会失效的,当ViewPager绘制完Item之后,ViewPager会把child标记为POSITION_UNCHANGED,这样就不会在notifyDataSetChanged后更新这个View了。当我们调用PagerAdapter的notifyDataSetChanged方法之后,系统会去Adapter的getItemPosition方法中遍历所有的child,我们在getItemPosition方法中改写返回值POSITION_NONE,表示child都没有绘制过,这样ViewPager就会去重绘了。

@Override

public void notifyDataSetChanged() {

    mChildCount = getCount();

    super.notifyDataSetChanged();

}



@Override

public int getItemPosition(Object object) {

    // 重写getItemPosition,保证每次获取时都强制重绘UI

    if (mChildCount > 0) {

        mChildCount--;

        return POSITION_NONE;

    }

    return super.getItemPosition(object);

}

我们增加一个mChildCount来记录子类的数量,在一定程度上减少重绘的次数。
因为重绘的时候,ViewPager会的Destory Item,增加了系统开销。

更加优化的方法

当我们只需要对ViewPager中的某些元素进行更新时,我们可以在instantiateItem方法调用时,用View.setTag方法加入标志,在需要更新View时,通过findViewWithTag的方法找到对应的View进行更新。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。