Viewpager 的相关总结
1、修改切换item的时间
public class FixedSpeedScroller extends Scroller { private int mDuration = 300; public FixedSpeedScroller(Context context) { super(context); } public FixedSpeedScroller(Context context, android.view.animation.Interpolator interpolator) { super(context, interpolator); } public FixedSpeedScroller(Context context, android.view.animation.Interpolator interpolator, boolean flywheel) { super(context, interpolator, flywheel); } @Override public void startScroll(int startX, int startY, int dx, int dy, int duration) { super.startScroll(startX, startY, dx, dy, mDuration); } @Override public void startScroll(int startX, int startY, int dx, int dy) { super.startScroll(startX, startY, dx, dy, mDuration); } }
private void setViewPagerScrollSpeed(){ try { Field mScroller = null; mScroller = ViewPager.class.getDeclaredField("mScroller"); if(mScroller != null){ mScroller.setAccessible(true); FixedSpeedScroller scroller = new FixedSpeedScroller( getContext(), new LinearInterpolator()); mScroller.set(mUserInfoViewPager, scroller); } }catch(NoSuchFieldException e){ }catch (IllegalArgumentException e){ }catch (IllegalAccessException e){ } }
2、修改Item的切换动画
mUserInfoViewPager.setPageTransformer(true, new PageTransformer() { private static final float MIN_SCALE = 0.85f; private static final float MIN_ALPHA = 0.5f; @Override public void transformPage(View view, float position) { // int pageWidth = view.getWidth(); int pageHeight = view.getHeight(); if (position < -1) { view.setAlpha(0); } else if (position <= 1) { //a页滑动至b页 ; a页从 0.0 -1 ;b页从1 ~ 0.0 // [-1,1] // Modify the default slide transition to shrink the page as well float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position)); float vertMargin = pageHeight * (1 - scaleFactor) / 2; float horzMargin = pageWidth * (1 - scaleFactor) / 2; if (position < 0){ view.setTranslationX(horzMargin - vertMargin / 2); } else { view.setTranslationX(-horzMargin + vertMargin / 2); } // Scale the page down (between MIN_SCALE and 1) view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); // Fade the page relative to its size. view.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE)/ (1 - MIN_SCALE) * (1 - MIN_ALPHA)); } else { // (1,+Infinity] // This page is way off-screen to the right. view.setAlpha(0); } } });
3、ViewPager实现Gallery类似效果
package com.joyodream.pingo.near.ui; import java.lang.reflect.Field; import android.content.Context; import android.graphics.Camera; import android.graphics.Matrix; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.LinearInterpolator; import android.view.animation.Transformation; import android.widget.Scroller; import com.joyodream.common.util.DipPixelUtil; /** * * 自定义的展示图片的控件 * 通过Camera 调整z轴距离,实现图片放大缩小 * * 注意: * 1、为了实现在屏幕上面看到多个Item,需要在滑动的过程中刷新父控件 * 2、另外,通过设置clipChildren = false,不去裁剪子控件的绘图区域 * 3、 * * @author lipeilong * */ public class NearViewPager extends ViewPager { /** * The camera class is used to 3D transformation matrix. */ private Camera mCamera = new Camera(); /** * The max zoom value (Z axis). */ private int mMaxZoom = -120; private int mMaxAlpha = 0x8f; private OnPageChangeListener mScrollListener; private int mScrollPosition; private int mScrollOffset; public int mCurPosition; private float mDownX; private float mDownY; private boolean mClick; public NearViewPager(Context context, AttributeSet attrs) { super(context, attrs); // init(); } public NearViewPager(Context context) { super(context); // init(); } private void init() { // Enable set transformation. this.setStaticTransformationsEnabled(true); // Enable set the children drawing order. this.setChildrenDrawingOrderEnabled(true); this.setOverScrollMode(ViewPager.OVER_SCROLL_NEVER); super.setOnPageChangeListener(new MyOnPageChangeListener()); setViewPagerScrollSpeed(); } private void setViewPagerScrollSpeed(){ try { Field mScroller = null; mScroller = ViewPager.class.getDeclaredField("mScroller"); if(mScroller != null){ mScroller.setAccessible(true); FixedSpeedScroller scroller = new FixedSpeedScroller( getContext(), new LinearInterpolator()); mScroller.set(this, scroller); } }catch(NoSuchFieldException e){ }catch (IllegalArgumentException e){ }catch (IllegalAccessException e){ } } @Override protected int getChildDrawingOrder(int childCount, int i) { // Current selected index. int selectedIndex = getCurrentItem(); if (selectedIndex < 0) { return i; } if (i < selectedIndex) { return i; } else if (i >= selectedIndex) { return childCount - 1 - i + selectedIndex; } else { return i; } } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); } @Override protected boolean getChildStaticTransformation(View child, Transformation t) { super.getChildStaticTransformation(child, t); t.clear(); t.setTransformationType(Transformation.TYPE_MATRIX); int index = findViewIndex(child); if(index != -1){ transformImageBitmap(child, t, index); } return true; } /** * * 找出子控件的索引 * @param child * @return */ private int findViewIndex(View child){ int index = (Integer) child.getTag(); return index; } /** * * 刷新所有的子控件,通过这个来触发 getChildStaticTransformation 的调用 * */ private void invalidateVisibleChilds() { for (int i = 0; i < getChildCount(); i++) { getChildAt(i).invalidate(); } } /** * * @param child * @param t * @param index */ private void transformImageBitmap(View child, Transformation t, int index) { mCamera.save(); final Matrix imageMatrix = t.getMatrix(); final int imageHeight = child.getHeight(); final int imageWidth = child.getWidth(); int width = getPageMargin() + imageWidth; if(index == mScrollPosition){ // 当前项从最大变化到最小 z轴变化范围 mMaxZoom *(1 -- 0) float dz = mMaxZoom * ( 1- mScrollOffset * 1f / width); int alpha = (int) (mMaxAlpha * mScrollOffset * 1f / width); mCamera.translate(0, 0, dz); if(child instanceof NearImageView){ ((NearImageView)child).setShadeAlpha(alpha); } }else if(index == mScrollPosition + 1){ // 当前项的后一项从最小变化到最大 ,z轴变化范围 mMaxZoom * (0 -- 1) float dz = mMaxZoom * mScrollOffset * 1f / width; int alpha = (int) (mMaxAlpha * ( 1- mScrollOffset * 1f / width )); mCamera.translate(0, 0, dz); if(child instanceof NearImageView){ ((NearImageView)child).setShadeAlpha(alpha); } }else { // 当前项的后2项或者前N项大小不发生变化,z轴不变 mCamera.translate(0, 0, 0); if(child instanceof NearImageView){ ((NearImageView)child).setShadeAlpha(mMaxAlpha); } } mCamera.getMatrix(imageMatrix); imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2)); imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2)); mCamera.restore(); } @Override public void setOnPageChangeListener(OnPageChangeListener listener) { mScrollListener = listener; }; /** * @author lipeilong * */ private class MyOnPageChangeListener implements OnPageChangeListener { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { if (mScrollListener != null) { mScrollListener.onPageScrolled(position, positionOffset, positionOffsetPixels); } mScrollPosition = position; mScrollOffset = positionOffsetPixels; // 刷新子控件 if(System.currentTimeMillis() % 2 == 0){ invalidateVisibleChilds(); } } @Override public void onPageSelected(int position) { mCurPosition = position; if (mScrollListener != null) { mScrollListener.onPageSelected(position); } } @Override public void onPageScrollStateChanged(final int state) { if (mScrollListener != null) { mScrollListener.onPageScrollStateChanged(state); } } } @Override public boolean onTouchEvent(MotionEvent ev) { // final float MAX_DISTANCE = 50; switch(ev.getAction()){ case MotionEvent.ACTION_DOWN: mDownX = ev.getRawX(); mDownY = ev.getRawY(); mClick = true; break; case MotionEvent.ACTION_UP: if(mClick && Math.abs(ev.getRawX()- mDownX) < MAX_DISTANCE && Math.abs(ev.getRawY() - mDownY) < MAX_DISTANCE){ // 点击事件 performMyClick(ev); } break; case MotionEvent.ACTION_MOVE: if(Math.abs(ev.getRawX()- mDownX) > MAX_DISTANCE || Math.abs(ev.getRawY() - mDownY) > MAX_DISTANCE){ mClick = false; } break; } return super.onTouchEvent(ev); } private void performMyClick(MotionEvent ev){ int index = getCurrentItem(); if(isAtLeft(ev)){ setCurrentItem(index - 1); }else if(isAtRight(ev)){ setCurrentItem(index + 1); } } private boolean isAtLeft(MotionEvent ev){ int margin = DipPixelUtil.dip2px(getContext(), 56); int left = getLeft() - margin; int right = getRight() + margin; int top = getTop(); int bottom = getBottom(); // 必须使用全局坐标,同时要减去title和通知栏高度 int x = (int) ev.getRawX(); int y = (int) ev.getRawY() - DipPixelUtil.dip2px(getContext(), 96); if(y > top && y < bottom){ if(x < left){ return true; } } return false; } private boolean isAtRight(MotionEvent ev){ int margin = DipPixelUtil.dip2px(getContext(), 56); int left = getLeft() - margin; int right = getRight() + margin; int top = getTop(); int bottom = getBottom(); int x = (int) ev.getRawX(); int y = (int) ev.getRawY() - DipPixelUtil.dip2px(getContext(), 96); if(y > top && y < bottom){ if(x > right){ return true; } } return false; } public class FixedSpeedScroller extends Scroller { private int mDuration = 300; public FixedSpeedScroller(Context context) { super(context); } public FixedSpeedScroller(Context context, android.view.animation.Interpolator interpolator) { super(context, interpolator); } public FixedSpeedScroller(Context context, android.view.animation.Interpolator interpolator, boolean flywheel) { super(context, interpolator, flywheel); } @Override public void startScroll(int startX, int startY, int dx, int dy, int duration) { super.startScroll(startX, startY, dx, dy, mDuration); } @Override public void startScroll(int startX, int startY, int dx, int dy) { super.startScroll(startX, startY, dx, dy, mDuration); } } }
注意:1、设置父控件、子控件的clipChildren=false 2、滑动的时候刷新子控件