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进行更新。