ViewPager高级用法大全

ViewPager是开发中经常都会用到的一个控件,相信大家已经非常熟悉了,有些高级用法可能对于某些新人来说,不是很熟悉,所以我想有必要总结一下。

1、设置页面是否可以滑动翻页

开发中也需会有这种需求,期望通过切换tab按钮来切换页面,而不是滑动翻页,但是我们又不可能每次点击tab按钮都重新加载一个页面,那效率太低了,因此我们可以

使用ViewPager来帮我们缓存页面。但是ViewPager默认是可以通过手势滑动切换页面的,那么如何禁止手势滑动切换页面呢?

    我们可以通过重写onInterceptTouchEvent和onTouchEvent,如果不想滑动翻页,则返回false,不拦截触摸事件。

	/**
	 * 是否可以滑动翻页
	 * 
	 * @param pagerEnabled
	 */
	public void setPagingEnabled(boolean pagerEnabled)
	{
		this.pagerEnabled = pagerEnabled;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (pagerEnabled) {
			return super.onTouchEvent(event);
		} else {
			return false;
		}
	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent event) {
		if (pagerEnabled) {
			return super.onInterceptTouchEvent(event);
		} else {
			return false;
		}

	}


2、设置滑动翻页的速度

     ViewPager默认的翻页速度比较快,如果想让翻页速度变得平滑一点,那么实现呢?

我们知道ViewPager类中有一个Scroller类型的成员变量,叫mScroller,就是用来控制滑动的。通过调用 mScroller.startScroll(sx, sy, dx, dy, duration)来实现页面滚动。这里

不对Scroller做过多介绍,大家只需知道使用Scroller可以完成页面的滚动就行了,而且系统大部分控件的滚动都是用Scroller来实现的。下面解释一下

mScroller.startScroll(sx, sy, dx, dy, duration) 方法的几个参数:

sx:开始x坐标

sy:开始y坐标

dx:x轴方向滚动的距离,负数向左,正数向右

dy:y轴方向滚动的距离,负数向上,正数向下

duration:滚动的时长

其中控制duration就可以控制滚动时长,ViewPager计算出来的滚动时长是比较短的,所以我们可以看到切换页面时非常快速就闪过了。如果想让页面切换变得平滑一点,

就可以控制duration.那么怎么在ViewPager调用mScroller.startScroll(sx, sy, dx, dy, duration)时改变duration呢,首先duration是ViewPager内部计算的,这个没法去改变,

还有就是可以通过重写startScroll方法。但是mScroller是ViewPager的私有变量,因此我们需要通过java的反射机制,注入我们自己的Scroller。

继承ViewPager,然后在ViewPager的构造函数中,通过反射注入我们自己的Scroller,

try {
			Class<?> viewpager = android.support.v4.view.ViewPager.class;
			Field scroller = viewpager.getDeclaredField("mScroller");
			scroller.setAccessible(true);
			Field interpolator = viewpager.getDeclaredField("sInterpolator");
			interpolator.setAccessible(true);

			mScroller = new CustomDurationScroller(getContext(),
					(Interpolator) interpolator.get(null));
			scroller.set(this, mScroller);
		} catch (Exception e) {
			e.printStackTrace();
		}

CustomDurationScroller就是我们自定义的Scroller

public class CustomDurationScroller extends Scroller {

	private float mScrollFactor = 1.0f;
	private float mFactor = mScrollFactor;

	public CustomDurationScroller(Context context) {
		super(context);
	}

	public CustomDurationScroller(Context context, Interpolator interpolator) {
		super(context, interpolator);
	}

	@SuppressLint("NewApi")
	public CustomDurationScroller(Context context, Interpolator interpolator, boolean flywheel) {
		super(context, interpolator, flywheel);
	}

	/**
	 * Set the factor by which the duration will change
	 */
	public void setScrollDurationFactor(float scrollFactor) {
		mFactor = mScrollFactor = scrollFactor;
	}

	public void resetDurationFactor() {
		mFactor = 1.0f;
	}

	public float getScrollDuraionFactor() {
		return mScrollFactor;
	}

	@Override
	public void startScroll(int startX, int startY, int dx, int dy, int duration) {
		super.startScroll(startX, startY, dx, dy, (int) (duration * mFactor));
	}

}

重写startScroll方法,通过设置滑动因子mFactor来改变滑动时长duration。

之后ViewPager调用mScroller的startScroll方法,duration都会改变,从而加快(mFactor>1)或放缓(mFactor<1)滚动速度。


3、一页显示多个item

ViewPager默认一页显示一个item,那么如何在一页显示多个item呢?


4、按照item实际高度动态调整

ViewPager默认会按item中最大的高度来调整自身的高度,比如第一个item的高度是300dp,第二个item的高度是150dp,则ViewPager的高度最后会按照300dp来显示,

导致第二个item的底部会留50dp的空白。那么针对这种item不一样高度的ViewPager,如何按item实际高度来展示呢?

public class WrapContentHeightViewPager extends common.widget.viewpager.ViewPager {

	public WrapContentHeightViewPager(Context context) {
		super(context);
	}

	public WrapContentHeightViewPager(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

		int height = 0;
		// 下面遍历所有child的高度
		int childCount = getChildCount();
		for (int i = 0; i < childCount; i++) {
			View child = getChildAt(i);
			child.measure(widthMeasureSpec,
					MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
			int h = child.getMeasuredHeight();
			if (h > height) // 采用最大的view的高度。
				height = h;
		}

		heightMeasureSpec = MeasureSpec.makeMeasureSpec(height,
				MeasureSpec.EXACTLY);

		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}
}

在xml中使用

 <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"        
        android:clipChildren="false"
        android:layerType="software" >

        <common.widget.viewpager.WrapContentHeightViewPager
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:overScrollMode="never" />
    </LinearLayout>


注意:

1) clipChildren=false,表示不裁剪ViewPager的绘制区域,利用这个属性可以控制一屏显示多的item。

2) 多个item之间的间隔可以通过viewPager.setPageMargin(margin)设置。


5、打造绚丽切换效果的ViewPager

实现PageTransformer,然后viewPager.setPageTransformer(PageTransformer transformer)来实现ViewPager的页面切换效果,其中属性动画可由

ninooldandroids进行实现。

android官网也提供好了几个写好的PageTransformer供参考。地址 http://developer.android.com/training/animation/screen-slide.html 

总结:

1)setPageTransformer在3.0以上才起作用,当然也可以设置代码兼容到3.0以下,但是现在的app最低版本应该都是4.0+了,所以没有多大必要兼容3.0以下了。

2)A页切换到B页
A页的position: 0.0 ~ -1

B页的position: 1 ~ 0.0

public class MyPagerTransformer implements ViewPager.PageTransformer {
    @Override
    public void transformPage(View page, float position) {
        if(position<-1) //[负无穷~-1)
        {

        }else if(position<=0) //A页 0.0~ -1.0
        { //[-1,0]


        }
        else if(position<=1)//B页 1.0~0.0
        {  //(0,1]

        }
        else   //(1,正无穷]
        {

        }
    }
}


利用这个变化规律,可以计算出我们自己想要的动画梯度值。结合属性动画,动态改变透明度、缩放值、位移、旋转等效果。


6、无限循环的ViewPager

实现ViewPager的无限滑动,有两种解决方案

1)实现一种假的无限循环,取一种最大值的思路,比如Integer.MAX_VALUE,然后将一页的初始位置通过setCurrentItem(position) 定位到 position=Integer.MAX_VALUE/2. 这样向左向右滑动都可以。这种做法一般来说也可以满足需求,因为要切换一个相当大的数才能到达末尾。但是毕竟不是最可靠的解决方案。

2)在存放View的集合中的第一个位置放入真正的最后一个View,而在最后一个放入第一个。具体可参考 http://blog.csdn.net/oweixiao123/article/details/23459041


以上就是ViewPager的一些高级用法,具体用法没有做过多说明,大家开发中有不明白的可百度或google,这里只是做一个用法的汇总,给大家一些思路,希望能帮到大家。












阅读更多
换一批

没有更多推荐了,返回首页