你的位置:首页 > 软件开发 > 操作系统 > 侧滑2

侧滑2

发布时间:2016-02-16 11:00:04
如下图是侧滑的效果图 实现的功能主要是用ViewDragHelper,用ViewDragHelper来自 ...

侧滑2

如下图是侧滑的效果图

           侧滑2                   侧滑2

 

实现的功能主要是用ViewDragHelper,用ViewDragHelper来自定义一个侧滑面板来实现侧滑

如下是自定义的侧滑面板

 1 package com.demo.sb.widget; 2  3 import com.nineoldandroids.view.ViewHelper; 4  5 import android.content.Context; 6 import android.graphics.Color; 7 import android.graphics.PorterDuff.Mode; 8 import android.support.v4.view.ViewCompat; 9 import android.support.v4.widget.ViewDragHelper; 10 import android.util.AttributeSet; 11 import android.util.Log; 12 import android.view.MotionEvent; 13 import android.view.View; 14 import android.view.ViewGroup; 15 import android.widget.FrameLayout; 16  17 /** 18  * 侧滑面板 19  *  20  * @author Administrator 21  *  22 */ 23 public class DragLayout extends FrameLayout { 24  25   private ViewDragHelper mDragHelper; 26   private ViewGroup mLeftContent; 27   private ViewGroup mMainContent; 28  29   private Status mStatus = Status.Close; 30   private OnDragStatusChangeListener mListener; 31  32   /** 33    * 状态枚举 34   */ 35   public static enum Status { 36     Close, Open, Draging; 37   } 38  39   public interface OnDragStatusChangeListener { 40     void onClose(); 41  42     void onOpen(); 43  44     void onDraging(float percent); 45   } 46  47   public Status getStatus() { 48     return mStatus; 49   } 50  51   public void setStatus(Status mStatus) { 52     this.mStatus = mStatus; 53   } 54  55   public void setDragStatusListener(OnDragStatusChangeListener mListener) { 56     this.mListener = mListener; 57   } 58  59   public DragLayout(Context context) { 60     this(context, null); 61     // TODO Auto-generated constructor stub 62   } 63  64   public DragLayout(Context context, AttributeSet attrs) { 65     this(context, attrs, 0); 66     // TODO Auto-generated constructor stub 67   } 68  69   public DragLayout(Context context, AttributeSet attrs, int defStyle) { 70     super(context, attrs, defStyle); 71     // TODO Auto-generated constructor stub 72     /** 73      * a . 初始化(通过静态的方法) 74     */ 75     mDragHelper = ViewDragHelper.create(this, mCallback); 76   } 77  78   /** 79    * c. 重写Callback的事件 80   */ 81   ViewDragHelper.Callback mCallback = new ViewDragHelper.Callback() { 82     /** 83      * 1. 根据返回结果决定当前的child是否可以拖拽 child 当前被拖拽的View pointerId 区分多点触摸的id 84     */ 85     @Override 86     public boolean tryCaptureView(View child, int pointerId) { 87       Log.d("jiejie", "tryCaptureView: " + child); 88       return true;// 都可以尝试被拖拽 89       // return child == mMainContent;//只有主程序的View可以被拖拽 90     } 91  92     public void onViewCaptured(View capturedChild, int activePointerId) { 93       // 当capturedChild被捕获时,调用 94       Log.d("jiejie", "onViewCaptured: " + capturedChild); 95     } 96  97     public int getViewHorizontalDragRange(View child) { 98       // 返回拖拽的范围,不对拖拽进行真正的限制。仅仅决定了动画的执行速度 99       return mRange;100     }101 102     /**103      * 2. 根据建议值 修正将要移动到的(横向)位置(重要) 此时还没有真正移动104     */105     public int clampViewPositionHorizontal(View child, int left, int dx) {106       Log.d("jiejie", "clampViewPositionHorizontal: " + left);107       if (child == mMainContent) {108         left = fixLeft(left);109       }110       return left;111     }112 113     /**114      * 3. 当View位置改变的时候,处理要做的事情(更新状态, 伴随动画, 重绘界面) 此时,View已经发生了位置的改变115      * changedView 改变位置的View left 新的左边值 dx 水平方向变化量116     */117     public void onViewPositionChanged(View changedView, int left, int top,118         int dx, int dy) {119       super.onViewPositionChanged(changedView, left, top, dx, dy);120       Log.d("jiejie", "onViewPositionChanged: " + "left:" + left121           + " dx: " + dx);122       int newLeft = left;123       if (changedView == mLeftContent) {124         // 把当前变化量专递给mMainContent125         newLeft = mMainContent.getLeft() + dx;126       }127       // 进行修正128       newLeft = fixLeft(newLeft);129 130       if (changedView == mLeftContent) {131         // 当左面板移动之后,再强制放回去132         mLeftContent.layout(0, 0, 0 + mWidth, 0 + mHeight);133         mMainContent.layout(newLeft, 0, newLeft + mWidth, 0 + mHeight);134       }135 136       /**137        * 更新状态时设置动画(也可以不设置,不设置的话则默认平滑的状态,也可以省很多代码) 设置左面板和主面板,背景的动画138       */139       dispatchDragEvent(newLeft);140 141       // 为了兼容低版本,每次修改值之后,进行重绘142       invalidate();143     }144 145     /**146      * 4. 当View被释放的时候,处理的事情(执行动画) View releasedChild 被释放的子View float xvel147      * 水平方向的速度,向右为正 float yvel 竖直方向的速度, 向下为正148     */149     public void onViewReleased(View releasedChild, float xvel, float yvel) {150       Log.d("jiejie", "onViewReleased: " + "xvel: " + xvel + "yvel: "151           + yvel);152       super.onViewReleased(releasedChild, xvel, yvel);153       // 判断执行 关闭/开启154       // 先考虑所有开启的情况,剩下的就是都是关闭的情况155       if (xvel == 0 && mMainContent.getLeft() > (mRange / 2.0f)) {156         open();157       } else if (xvel > 0) {158         open();159       } else {160         chose();161       }162     }163 164     public void onViewDragStateChanged(int state) {165       super.onViewDragStateChanged(state);166     }167   };168 169   /**170    * 根据范围修正左边值171    * 172    * @param left173    * @return174   */175   private int fixLeft(int left) {176     if (left < 0) {177       return 0;178     } else if (left > mRange) {179       return mRange;180     }181     return left;182   }183 184   /**185    * 执行动画186    * 187    * @param newLeft188   */189   protected void dispatchDragEvent(int newLeft) {190     // TODO Auto-generated method stub191     float percent = newLeft * 1.0f / mRange;192     Log.d("jiejie", "percent: " + percent);193     if (mListener != null) {194       mListener.onDraging(percent);195     }196 197     // 更新状态,执行回调198     Status preStatus = mStatus;199     mStatus = updateStatus(percent);200 201     if (mStatus != preStatus) {202       // 状态发生变化203       if (mStatus == Status.Close) {204         // 当前变为关闭状态205         if (mListener != null) {206           mListener.onClose();207         }208       } else if (mStatus == Status.Open) {209         if (mListener != null) {210           mListener.onOpen();211         }212       }213     }214 215     // 伴随动画216     animViews(percent);217   }218 219   private Status updateStatus(float percent) {220     if (percent == 0f) {221       return Status.Close;222     } else if (percent == 1.0f) {223       return Status.Open;224     }225     return Status.Draging;226   }227 228   private void animViews(float percent) {229     // TODO Auto-generated method stub230     /**231      * >1.左面板:缩放动画,平移动画,透明度动画 缩放动画0.0 - > 1.0 >> 0.5f -> 1.0f >>>232      * 0.5f*percent+0.5f mLeftContent.setScaleX(0.5f + 0.5f * percent);233      * mLeftContent.setScaleY(0.5f + 0.5f * percent);234     */235     // mLeftContent.setScaleY(0.5f + 0.5f * percent);236     // mLeftContent.setScaleX(0.5f + 0.5f * percent);237     ViewHelper.setScaleX(mLeftContent, evaluate(percent, 0.5f, 1.0f));238     ViewHelper.setScaleY(mLeftContent, 0.5f + 0.5f * percent);239     // 平移动画:-mWidth / 2.0 f - > 0.0f240     ViewHelper.setTranslationX(mLeftContent,241         evaluate(percent, -mWidth / 2.0f, 0));242     // 透明度: 0.5 -> 1.0f243     ViewHelper.setAlpha(mLeftContent, evaluate(percent, 0.5f, 1.0f));244 245     /**246      * >2. 主面板:缩放动画247     */248     // 1.0f -> 0.8f249     ViewHelper.setScaleX(mMainContent, evaluate(percent, 1.0f, 0.8f));250     ViewHelper.setScaleY(mMainContent, evaluate(percent, 1.0f, 0.8f));251 252     /**253      * >3. 背景动画: 亮度变化(颜色变化)254     */255     getBackground()256         .setColorFilter(257             (Integer) evaluateColor(percent, Color.BLACK,258                 Color.TRANSPARENT), Mode.SRC_OVER);259   }260 261   /**262    * 估值器263    * 264    * @param fraction265    * @param startValue266    * @param endValue267    * @return268   */269   public Float evaluate(float fraction, Number startValue, Number endValue) {270     float startFloat = startValue.floatValue();271     return startFloat + fraction * (endValue.floatValue() - startFloat);272   }273 274   /**275    * 颜色变化过度276    * 277    * @param fraction278    * @param startValue279    * @param endValue280    * @return281   */282   public Object evaluateColor(float fraction, Object startValue,283       Object endValue) {284     int startInt = (Integer) startValue;285     int startA = (startInt >> 24) & 0xff;286     int startR = (startInt >> 16) & 0xff;287     int startG = (startInt >> 8) & 0xff;288     int startB = startInt & 0xff;289 290     int endInt = (Integer) endValue;291     int endA = (endInt >> 24) & 0xff;292     int endR = (endInt >> 16) & 0xff;293     int endG = (endInt >> 8) & 0xff;294     int endB = endInt & 0xff;295 296     return (int) ((startA + (int) (fraction * (endA - startA))) << 24)297         | (int) ((startR + (int) (fraction * (endR - startR))) << 16)298         | (int) ((startG + (int) (fraction * (endG - startG))) << 8)299         | (int) ((startB + (int) (fraction * (endB - startB))));300   }301 302   @Override303   public void computeScroll() {304     // TODO Auto-generated method stub305     super.computeScroll();306     // 2. 持续平滑动画(高频率调用)307     if (mDragHelper.continueSettling(true)) {308       // 如果返回true,动画还需要继续执行309       ViewCompat.postInvalidateOnAnimation(this);310     }311   }312 313   // public void chose() {314   // // TODO Auto-generated method stub315   // chose(true);316   // }317   public void chose() {318     // TODO Auto-generated method stub319     chose(true);320   }321 322   /**323    * 关闭324    * 325    * @param b326   */327   public void chose(boolean isSmooth) {328     // TODO Auto-generated method stub329     int finalLeft = 0;330     // 1. 触发一个平滑动画331     if (isSmooth) {332       if (mDragHelper.smoothSlideViewTo(mMainContent, finalLeft, 0)) {333         // 返回true代表还没有移动到指定位置,需要刷新界面334         // 参数传this(child所在的ViewGroup)335         ViewCompat.postInvalidateOnAnimation(this);336       }337     } else {338       mMainContent.layout(finalLeft, 0, finalLeft + mWidth, 0 + mHeight);339     }340   }341 342   public void open() {343     // TODO Auto-generated method stub344     open(true);345   }346 347   /**348    * 开启349    * 350    * @param b351   */352   public void open(boolean isSmooth) {353     // TODO Auto-generated method stub354     int finalLeft = mRange;355     if (isSmooth) {356       // 1. 触发一个平滑动画357       if (mDragHelper.smoothSlideViewTo(mMainContent, finalLeft, 0)) {358         // 返回true代表还没有移动到指定位置,需要刷新界面359         // 参数this(child所在的ViewGroup)360         ViewCompat.postInvalidateOnAnimation(this);361       }362     } else {363       mMainContent.layout(finalLeft, 0, finalLeft + mWidth, 0 + mHeight);364     }365   }366 367   /**368    * b. 专递触摸事件369   */370   public boolean onInterceptTouchEvent(MotionEvent ev) {371     // 传递给mDragHandler372     return mDragHelper.shouldInterceptTouchEvent(ev);373   };374 375   @Override376   public boolean onTouchEvent(MotionEvent event) {377     // TODO Auto-generated method stub378     try {379       mDragHelper.processTouchEvent(event);380     } catch (Exception e) {381       e.printStackTrace();382     }383     // 返回true,持续接收事件384     return true;385   }386 387   /**388    * 当View中所有的子控件 均被映射成389   */390   @Override391   protected void onFinishInflate() {392     // TODO Auto-generated method stub393     super.onFinishInflate();394     if (getChildCount() < 2) {395       throw new IllegalAccessError(396           "布局至少有2个孩子. Your ViewGroup must have 2 children at least");397     }398     if (!(getChildAt(0) instanceof ViewGroup && getChildAt(1) instanceof ViewGroup)) {399       throw new IllegalArgumentException(400           "子View必须是ViewGroup的子类. Your children must be an instance of ViewGroup");401     }402     mLeftContent = (ViewGroup) getChildAt(0);403     mMainContent = (ViewGroup) getChildAt(1);404   }405 406   /**407    * 当view的大小发生变化时触发408   */409   private int mRange;410   private int mHeight;411   private int mWidth;412 413   @Override414   protected void onSizeChanged(int w, int h, int oldw, int oldh) {415     // 当尺寸有变化的时候调用416     super.onSizeChanged(w, h, oldw, oldh);417     mHeight = getMeasuredHeight();418     mWidth = getMeasuredWidth();419     mRange = (int) (mWidth * 0.6f);420   }421 422 }

 

海外公司注册、海外银行开户、跨境平台代入驻、VAT、EPR等知识和在线办理:https://www.xlkjsw.com

原标题:侧滑2

关键词:

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

可能感兴趣文章

我的浏览记录