900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > android自定义ViewPager之——3D效果应用

android自定义ViewPager之——3D效果应用

时间:2023-11-17 18:00:43

相关推荐

android自定义ViewPager之——3D效果应用

今天在github里看到一个3D效果的ViewPager,感觉做出来的ViewPager滑动的时候效果十分的炫,就check out下来研究了一下如何实现的,以及如何使用,将整个ViewPager稍加修改后(主要是处理了一下与项目中其它控滑动控件的事件冲突)后,应用到了自己现在项目中。感觉这个效果真的非常的不错,现在把自己写的一个Demo分享出来。

下面是这个ViewPager嵌入到项目中的效果图:

修改以后,在切换ViewPager时会有立体感,会为自己的应用增色不少。下面把使用的Demo发出来,其实与使用普通的ViewPager完全一样,只不过好像只能用PagerAdapter及其子类Adapter为它填充数据。

1.ViewPager3D源码:

public class ViewPager3D extends ViewPager{/*** maximum overscroll rotation of the children is 90 divided by this value*/final static float DEFAULT_OVERSCROLL_ROTATION = 2f;/*** maximum z distance to translate child view*/final static int DEFAULT_OVERSCROLL_TRANSLATION = 150;/*** maximum z distanze during swipe*/final static int DEFAULT_SWIPE_TRANSLATION = 100;/*** maximum rotation during swipe is 90 divided by this value*/final static float DEFAULT_SWIPE_ROTATION = 3;/*** duration of overscroll animation in ms*/final private static int DEFAULT_OVERSCROLL_ANIMATION_DURATION = 400;/*** if true alpha of children gets animated during swipe and overscroll*/final private static boolean DEFAULT_ANIMATE_ALPHA = true;@SuppressWarnings("unused")private final static String DEBUG_TAG = ViewPager.class.getSimpleName();private final static int INVALID_POINTER_ID = -1;private final static double RADIANS = 180f / Math.PI;/*** @author renard*/private class OverscrollEffect{private float mOverscroll;private Animator mAnimator;/*** @param deltaDistance [0..1] 0->no overscroll, 1>full overscroll*/public void setPull(final float deltaDistance){mOverscroll = deltaDistance;invalidateVisibleChilds();}/*** called when finger is released. starts to animate back to default* position*/private void onRelease(){if (mAnimator != null && mAnimator.isRunning()){mAnimator.addListener(new AnimatorListener(){@Overridepublic void onAnimationStart(Animator animation){}@Overridepublic void onAnimationRepeat(Animator animation){}@Overridepublic void onAnimationEnd(Animator animation){startAnimation(0);}@Overridepublic void onAnimationCancel(Animator animation){}});mAnimator.cancel();}else{startAnimation(0);}}private void startAnimation(final float target){mAnimator = ObjectAnimator.ofFloat(this, "pull", mOverscroll, target);mAnimator.setInterpolator(new DecelerateInterpolator());final float scale = Math.abs(target - mOverscroll);mAnimator.setDuration((long) (mOverscrollAnimationDuration * scale));mAnimator.start();}private boolean isOverscrolling(){if (mScrollPosition == 0 && mOverscroll < 0){return true;}if (getAdapter() != null){final boolean isLast = (getAdapter().getCount() - 1) == mScrollPosition;if (isLast && mOverscroll > 0){return true;}}return false;}}final private OverscrollEffect mOverscrollEffect = new OverscrollEffect();final private Camera mCamera = new Camera();private OnPageChangeListener mScrollListener;private float mLastMotionX;private int mActivePointerId;private int mScrollPosition;private float mScrollPositionOffset;private int mScrollPositionOffsetPixels;final private int mTouchSlop;private float mOverscrollRotation;private float mSwipeRotation;private int mOverscrollTranslation;private int mSwipeTranslation;private int mOverscrollAnimationDuration;private boolean mAnimateAlpha;private Rect mTempTect = new Rect();public ViewPager3D(Context context, AttributeSet attrs){super(context, attrs);setStaticTransformationsEnabled(true);final ViewConfiguration configuration = ViewConfiguration.get(context);mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);super.setOnPageChangeListener(new MyOnPageChangeListener());init(attrs);}private void init(AttributeSet attrs){TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ViewPager3D);mOverscrollRotation = a.getFloat(R.styleable.ViewPager3D_overscroll_rotation, DEFAULT_OVERSCROLL_ROTATION);mSwipeRotation = a.getFloat(R.styleable.ViewPager3D_swipe_rotation, DEFAULT_SWIPE_ROTATION);mSwipeTranslation = a.getInt(R.styleable.ViewPager3D_swipe_translation, DEFAULT_SWIPE_TRANSLATION);mOverscrollTranslation = a.getInt(R.styleable.ViewPager3D_overscroll_translation,DEFAULT_OVERSCROLL_TRANSLATION);mOverscrollAnimationDuration = a.getInt(R.styleable.ViewPager3D_overscroll_animation_duration,DEFAULT_OVERSCROLL_ANIMATION_DURATION);mAnimateAlpha = a.getBoolean(R.styleable.ViewPager3D_animate_alpha, DEFAULT_ANIMATE_ALPHA);a.recycle();}public boolean isAnimateAlpha(){return mAnimateAlpha;}public void setAnimateAlpha(boolean mAnimateAlpha){this.mAnimateAlpha = mAnimateAlpha;}public int getOverscrollAnimationDuration(){return mOverscrollAnimationDuration;}public void setOverscrollAnimationDuration(int mOverscrollAnimationDuration){this.mOverscrollAnimationDuration = mOverscrollAnimationDuration;}public int getSwipeTranslation(){return mSwipeTranslation;}public void setSwipeTranslation(int mSwipeTranslation){this.mSwipeTranslation = mSwipeTranslation;}public int getOverscrollTranslation(){return mOverscrollTranslation;}public void setOverscrollTranslation(int mOverscrollTranslation){this.mOverscrollTranslation = mOverscrollTranslation;}public float getSwipeRotation(){return mSwipeRotation;}public void setSwipeRotation(float mSwipeRotation){this.mSwipeRotation = mSwipeRotation;}public float getOverscrollRotation(){return mOverscrollRotation;}public void setOverscrollRotation(float mOverscrollRotation){this.mOverscrollRotation = mOverscrollRotation;}@Overridepublic void setOnPageChangeListener(OnPageChangeListener listener){mScrollListener = listener;};private void invalidateVisibleChilds(){for (int i = 0; i < getChildCount(); i++){final View childAt = getChildAt(i);childAt.getLocalVisibleRect(mTempTect);final int area = mTempTect.width() * mTempTect.height();if (area > 0){childAt.invalidate();}}invalidate();}private class MyOnPageChangeListener implements OnPageChangeListener{@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels){if (mScrollListener != null){mScrollListener.onPageScrolled(position, positionOffset, positionOffsetPixels);}mScrollPosition = position;mScrollPositionOffset = positionOffset;mScrollPositionOffsetPixels = positionOffsetPixels;// Log.i(DEBUG_TAG, "mScrollPosition = " + position + " offset = " + String.format("%f.2", positionOffset));// Log.i(DEBUG_TAG, "onPageScrolled");invalidateVisibleChilds();}@Overridepublic void onPageSelected(int position){if (mScrollListener != null){mScrollListener.onPageSelected(position);}}@Overridepublic void onPageScrollStateChanged(final int state){if (mScrollListener != null){mScrollListener.onPageScrollStateChanged(state);}if (state == SCROLL_STATE_IDLE){mScrollPositionOffset = 0;}}}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev){final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;switch (action){case MotionEvent.ACTION_DOWN:{mLastMotionX = ev.getX();mActivePointerId = MotionEventCompat.getPointerId(ev, 0);break;}case MotionEventCompat.ACTION_POINTER_DOWN:{final int index = MotionEventCompat.getActionIndex(ev);final float x = MotionEventCompat.getX(ev, index);mLastMotionX = x;mActivePointerId = MotionEventCompat.getPointerId(ev, index);break;}}return super.onInterceptTouchEvent(ev);}@Overridepublic boolean onTouchEvent(MotionEvent ev){boolean callSuper = false;final int action = ev.getAction();switch (action){case MotionEvent.ACTION_DOWN:{callSuper = true;mLastMotionX = ev.getX();mActivePointerId = MotionEventCompat.getPointerId(ev, 0);break;}case MotionEventCompat.ACTION_POINTER_DOWN:{callSuper = true;final int index = MotionEventCompat.getActionIndex(ev);final float x = MotionEventCompat.getX(ev, index);mLastMotionX = x;mActivePointerId = MotionEventCompat.getPointerId(ev, index);break;}case MotionEvent.ACTION_MOVE:{if (mActivePointerId != INVALID_POINTER_ID){// Scroll to follow the motion eventfinal int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);final float x = MotionEventCompat.getX(ev, activePointerIndex);final float deltaX = mLastMotionX - x;final int width = getWidth();final int widthWithMargin = width + getPageMargin();final int lastItemIndex = getAdapter().getCount() - 1;final int currentItemIndex = getCurrentItem();final float leftBound = Math.max(0, (currentItemIndex - 1) * widthWithMargin);final float rightBound = Math.min(currentItemIndex + 1, lastItemIndex) * widthWithMargin;if (mScrollPositionOffset == 0){if (currentItemIndex == 0){if (leftBound == 0){final float over = deltaX + mTouchSlop;mOverscrollEffect.setPull(over / width);}}else if (lastItemIndex == currentItemIndex){if (rightBound == lastItemIndex * widthWithMargin){final float over = deltaX - mTouchSlop;mOverscrollEffect.setPull(over / width);}}}else{mLastMotionX = x;}}else{mOverscrollEffect.onRelease();}break;}case MotionEvent.ACTION_UP:case MotionEvent.ACTION_CANCEL:{callSuper = true;mActivePointerId = INVALID_POINTER_ID;mOverscrollEffect.onRelease();break;}case MotionEvent.ACTION_POINTER_UP:{final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);if (pointerId == mActivePointerId){// This was our active pointer going up. Choose a new// active pointer and adjust accordingly.final int newPointerIndex = pointerIndex == 0 ? 1 : 0;mLastMotionX = ev.getX(newPointerIndex);mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);callSuper = true;}break;}}if (mOverscrollEffect.isOverscrolling() && !callSuper){return true;}else{try{return super.onTouchEvent(ev);}catch (IllegalArgumentException ignore){}catch (ArrayIndexOutOfBoundsException ignore){}return false;}}@Overrideprotected boolean getChildStaticTransformation(View child, Transformation t){if (child.getWidth() == 0){return false;}final boolean isFirstOrLast = mScrollPosition == 0 || (mScrollPosition == (getAdapter().getCount() - 1));if (mOverscrollEffect.isOverscrolling() && isFirstOrLast){final float dx = getWidth() / 2;final int dy = getHeight() / 2;t.getMatrix().reset();final float translateZ = (float) (mOverscrollTranslation * Math.sin(Math.PI* Math.abs(mOverscrollEffect.mOverscroll)));final float degrees = 90 / mOverscrollRotation- (float) ((RADIANS * Math.acos(mOverscrollEffect.mOverscroll)) / mOverscrollRotation);mCamera.save();mCamera.rotateY(degrees);mCamera.translate(0, 0, translateZ);mCamera.getMatrix(t.getMatrix());mCamera.restore();t.getMatrix().preTranslate(-dx, -dy);t.getMatrix().postTranslate(dx, dy);if (mAnimateAlpha){t.setTransformationType(Transformation.TYPE_BOTH);t.setAlpha((FloatMath.sin((float) ((1 - Math.abs(mOverscrollEffect.mOverscroll)) * Math.PI / 2))));}return true;}else if (mScrollPositionOffset > 0){final float dx = getWidth() / 2;final float dy = getHeight() / 2;double degrees = 0;child.getLocalVisibleRect(mTempTect);if (mTempTect.left >= mScrollPositionOffsetPixels){if (mAnimateAlpha){t.setTransformationType(Transformation.TYPE_BOTH);t.setAlpha((FloatMath.sin((float) (mScrollPositionOffset * Math.PI / 2))));}// right sidedegrees = (90 / mSwipeRotation) - (RADIANS * Math.acos(mScrollPositionOffset)) / mSwipeRotation;}else if (mTempTect.left == 0){if (mAnimateAlpha){t.setTransformationType(Transformation.TYPE_BOTH);t.setAlpha((FloatMath.sin((float) (mScrollPositionOffset * Math.PI / 2 + Math.PI / 2))));}// left sidedegrees = -(90 / mSwipeRotation) + (RADIANS * Math.acos(1 - mScrollPositionOffset)) / mSwipeRotation;}final float translateZ = (mSwipeTranslation * FloatMath.sin((float) ((Math.PI) * mScrollPositionOffset)));// Log.i(DEBUG_TAG, visibleRect.left+ ", " + mScrollPositionOffsetPixels + ", degress = "+// String.format("%f.2", degrees));t.getMatrix().reset();mCamera.save();mCamera.rotateY((float) degrees);mCamera.translate(0, 0, translateZ);mCamera.getMatrix(t.getMatrix());mCamera.restore();// pivot point is center of childt.getMatrix().preTranslate(-dx, -dy);t.getMatrix().postTranslate(dx, dy);// child.invalidate();return true;}return false;}}

2.Activity中使用ViewPager3D

package com.example.pageradapterdemo;import java.util.ArrayList;import android.os.Bundle;import android.support.v4.app.FragmentActivity;import mon.widget.scrollviewpager.ViewPager3D;public class MainActivity extends FragmentActivity{private ViewPager3D mViewPager;private CommonFragmentAdapter mAdapter;private ArrayList<MyFragment> mList;@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initData();initView();}private void initView(){mViewPager = (ViewPager3D) findViewById(R.id.viewpager);mAdapter = new CommonFragmentAdapter(MainActivity.this, getSupportFragmentManager(), mList);mViewPager.setAdapter(mAdapter);}private void initData(){mList = new ArrayList<MyFragment>();MyFragment layout1 = new MyFragment("One Fragment");MyFragment layout2 = new MyFragment("Two Fragment");MyFragment layout3 = new MyFragment("Three Fragment");mList.add(layout1);mList.add(layout2);mList.add(layout3);}}

monFragemntAdapter为ViewPager3D填充Fragment

public class CommonFragmentAdapter extends FragmentStatePagerAdapter{private ArrayList<MyFragment> fragmentList;public CommonFragmentAdapter(Activity activity, FragmentManager fm, ArrayList<MyFragment> fragmentList){super(fm);this.fragmentList = fragmentList;}@Overridepublic Fragment getItem(int arg0){return fragmentList.get(arg0);}@Overridepublic int getCount(){return fragmentList.size();}@Overridepublic void destroyItem(ViewGroup container, int position, Object object){super.destroyItem(container, position, object);}}

总结:将ViewPager3D当作一个普通的ViewPager来使用即可。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。