android自定义ViewPager水平滑动d性效果

android自定义ViewPager水平滑动d性效果,第1张

概述androidViewPager是一个经常要用到的组件,但android系统本身为我们提供的ViewPager是没有任何效果的,只能是一页一页的滑动,这样会让人感觉很死板,在看一些知名大公司的App时,看到了他们的ViewPager在滑动到最开

androID VIEwPager是一个经常要用到的组件,但androID系统本身为我们提供的VIEwPager是没有任何效果的,只能是一页一页的滑动,这样会让人感觉很死板,在看一些知名大公司的App时,看到了他们的VIEwPager在滑动到最开始或者最后的时候是有一个d性效果的,使用起来感觉非常的好,于是乎就是百度搜了一下,在StackOverflow中看到一篇文章就是讲如何实现这个效果的。

先看下效果图:滑动到最后一页时仍然可以拉动……

代码如下:

package com.example.myvIEwpager;  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.nineoldandroIDs.animation.Animator; import com.nineoldandroIDs.animation.Animator.AnimatorListener; import com.nineoldandroIDs.animation.ObjectAnimator;  public class BounceBackVIEwPager extends VIEwPager {   /**   * maximum z distance to translate child vIEw   */  final static int DEFAulT_OVERSCRolL_TRANSLATION = 500;   /**   * 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_bounce,DEFAulT_OVERSCRolL_TRANSLATION);   mOverscrollAnimationDuration = a.getInt(R.styleable.BounceBackVIEwPager_overscroll_animation_duration_bounce,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().@R_403_5990@();    final float translateX = (float) mOverscrollTranslation      * (mOverscrollEffect.mOverscroll > 0 ? Math.min(mOverscrollEffect.mOverscroll,1) : Math.max(        mOverscrollEffect.mOverscroll,-1));    mCamera.save();    mCamera.translate(-translateX,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;  } } 

自定义属性如下:

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的android自定义ViewPager水平滑动d性效果全部内容,希望文章能够帮你解决android自定义ViewPager水平滑动d性效果所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1143278.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-31
下一篇2022-05-31

发表评论

登录后才能评论

评论列表(0条)

    保存