android viewpager 弹性效果的实现,首页往左拉弹回,尾页往右拉弹回

这个实现,我今天找了蛮久,最后决定用的方法是这个:

http://stackoverflow.com/questions/13759862/android-viewpager-how-to-achieve-the-bound-effect

直接按照上面的方法用这个就ok了,我实验了一下效果还非常不错.网上所说的多加两个空白页的方法纯属娱乐感觉.

BounceBackViewPager 

直接在这里贴出吧

package com.lindo.collector.widget;

import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Camera;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ViewConfigurationCompat;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Transformation;

import com.lindo.collector.R;

public class BounceBackViewPager extends ViewPager {

	/**
	 * maximum z distance to translate child view
	 */
	final static int DEFAULT_OVERSCROLL_TRANSLATION = 150;

	/**
	 * duration of overscroll animation in ms
	 */
	final private static int DEFAULT_OVERSCROLL_ANIMATION_DURATION = 400;

	@SuppressWarnings("unused")
	private final static String DEBUG_TAG = ViewPager.class.getSimpleName();
	private final static int INVALID_POINTER_ID = -1;

	/**
	 * 
	 * @author renard, extended by Piotr Zawadzki
	 * 
	 */
	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(mLastPosition);
	    }

	    /**
	     * called when finger is released. starts to animate back to default position
	     */
	    private void onRelease() {
	        if (mAnimator != null && mAnimator.isRunning()) {
	            mAnimator.addListener(new AnimatorListener() {

	                @Override
	                public void onAnimationStart(Animator animation) {
	                }

	                @Override
	                public void onAnimationRepeat(Animator animation) {
	                }

	                @Override
	                public void onAnimationEnd(Animator animation) {
	                    startAnimation(0);
	                }

	                @Override
	                public 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;
	        }
	        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;
	final private int mTouchSlop;

	private float mOverscrollTranslation;
	private int mOverscrollAnimationDuration;

	public BounceBackViewPager(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.BounceBackViewPager);
	    mOverscrollTranslation = a.getDimension(R.styleable.BounceBackViewPager_overscroll_translation, DEFAULT_OVERSCROLL_TRANSLATION);
	    mOverscrollAnimationDuration = a.getInt(R.styleable.BounceBackViewPager_overscroll_animation_duration, DEFAULT_OVERSCROLL_ANIMATION_DURATION);
	    a.recycle();
	}

	public int getOverscrollAnimationDuration() {
	    return mOverscrollAnimationDuration;
	}

	public void setOverscrollAnimationDuration(int mOverscrollAnimationDuration) {
	    this.mOverscrollAnimationDuration = mOverscrollAnimationDuration;
	}

	public float getOverscrollTranslation() {
	    return mOverscrollTranslation;
	}

	public void setOverscrollTranslation(int mOverscrollTranslation) {
	    this.mOverscrollTranslation = mOverscrollTranslation;
	}

	@Override
	public void setOnPageChangeListener(OnPageChangeListener listener) {
	    mScrollListener = listener;
	};

	private void invalidateVisibleChilds(final int position) {
	     for (int i = 0; i < getChildCount(); i++) {
	     getChildAt(i).invalidate();

	     }
	    //this.invalidate();
	    // final View child = getChildAt(position);
	    // final View previous = getChildAt(position - 1);
	    // final View next = getChildAt(position + 1);
	    // if (child != null) {
	    // child.invalidate();
	    // }
	    // if (previous != null) {
	    // previous.invalidate();
	    // }
	    // if (next != null) {
	    // next.invalidate();
	    // }
	}

	private int mLastPosition = 0;

	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;
	        mScrollPositionOffset = positionOffset;
	        mLastPosition = position;
	        invalidateVisibleChilds(position);
	    }

	    @Override
	    public void onPageSelected(int position) {

	        if (mScrollListener != null) {
	            mScrollListener.onPageSelected(position);
	        }
	    }

	    @Override
	    public void onPageScrollStateChanged(final int state) {

	        if (mScrollListener != null) {
	            mScrollListener.onPageScrollStateChanged(state);
	        }
	        if (state == SCROLL_STATE_IDLE) {
	            mScrollPositionOffset = 0;
	        }
	    }
	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
	    try {
	        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);
	    } catch (IllegalArgumentException e) {
	        e.printStackTrace();
	        return false;
	    } catch (ArrayIndexOutOfBoundsException e) {
	        e.printStackTrace();
	        return false;
	    }
	}

	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
	    try {
	        return super.dispatchTouchEvent(ev);
	    } catch (IllegalArgumentException e) {
	        e.printStackTrace();
	        return false;
	    } catch (ArrayIndexOutOfBoundsException e) {
	        e.printStackTrace();
	        return false;
	    }
	}

	@Override
	public 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 event
	            final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
	            final float x = MotionEventCompat.getX(ev, activePointerIndex);
	            final float deltaX = mLastMotionX - x;
	            final float oldScrollX = getScrollX();
	            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;
	            final float scrollX = oldScrollX + deltaX;
	            if (mScrollPositionOffset == 0) {
	                if (scrollX < leftBound) {
	                    if (leftBound == 0) {
	                        final float over = deltaX + mTouchSlop;
	                        mOverscrollEffect.setPull(over / width);
	                    }
	                } else if (scrollX > rightBound) {
	                    if (rightBound == lastItemIndex * widthWithMargin) {
	                        final float over = scrollX - rightBound - 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 {
	        return super.onTouchEvent(ev);
	    }
	}

	@Override
	protected boolean getChildStaticTransformation(View child, Transformation t) {
	    if (child.getWidth() == 0) {
	        return false;
	    }
	    final int position = child.getLeft() / child.getWidth();
	    final boolean isFirstOrLast = position == 0 || (position == getAdapter().getCount() - 1);
	    if (mOverscrollEffect.isOverscrolling() && isFirstOrLast) {
	        final float dx = getWidth() / 2;
	        final int dy = getHeight() / 2;
	        t.getMatrix().reset();
	        final float translateX =(float) mOverscrollTranslation * (mOverscrollEffect.mOverscroll > 0 ? Math.min(mOverscrollEffect.mOverscroll, 1) : Math.max(mOverscrollEffect.mOverscroll, -1));
	        mCamera.save();
	        mCamera.translate(-translateX, 0, 0);
	        mCamera.getMatrix(t.getMatrix());
	        mCamera.restore();
	        t.getMatrix().preTranslate(-dx, -dy);
	        t.getMatrix().postTranslate(dx, dy);

	        if (getChildCount() == 1) {
	            this.invalidate();
	        } else {
	            child.invalidate();
	        }
	        return true;
	    }
	    return false;
	}
}

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
 
    
    <declare-styleable name="BounceBackViewPager">
    <!--
    determines the maximum amount of translation along the z-axis during the overscroll. 
    Default is 150.
    -->
    <attr name="overscroll_translation" format="dimension" />

    <!-- Duration of animation when user releases the over scroll. Default is 400 ms. -->
    <attr name="overscroll_animation_duration" format="integer" />
</declare-styleable>
</resources>

就是用这个

BounceBackViewPager 
然后在styles 里面加上上面的resources代码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Android实现右滑动动画,可以使用ViewPager。ViewPager是一个视图容器,可以让用户在屏幕上右滑动,以便浏览多个页面。 下面是一些步骤,以实现ViewPager右滑动翻页效果: 1. 在布局文件中添加ViewPager。 ```xml <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#FFFFFF" /> ``` 2. 在MainActivity中,创建一个PagerAdapter类,它将管理页面。 ```java public class MyPagerAdapter extends PagerAdapter { private List<View> viewList; public MyPagerAdapter(List<View> viewList) { this.viewList = viewList; } @Override public int getCount() { return viewList.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(viewList.get(position)); } @Override public Object instantiateItem(ViewGroup container, int position) { container.addView(viewList.get(position)); return viewList.get(position); } } ``` 3. 在MainActivity中,为ViewPager设置PagerAdapter。 ```java ViewPager viewPager = findViewById(R.id.viewPager); List<View> viewList = new ArrayList<>(); viewList.add(new View(this)); viewList.add(new View(this)); viewList.add(new View(this)); MyPagerAdapter adapter = new MyPagerAdapter(viewList); viewPager.setAdapter(adapter); ``` 现在,当用户在ViewPager中右滑动时,页面将滑动到下一页,实现右滑动翻页效果。 当然,你可以在PagerAdapter中添加自己的View,以实现更多的自定义效果

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值