package com.wise.customView; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.widget.Scroller; /** * 滑动删除控件 * @author honesty */ public class SlidingView extends ViewGroup{ /** * 滑动控件 */ Scroller mScroller; /** * 滑动速度对象 */ VelocityTracker velocityTracker; private int mTouchSlop; /** * 右边控件宽度 */ private int rightWidth = 200; /** * 滑动速度 */ private static final int SNAP_VELOCITY = 300; public SlidingView(Context context, AttributeSet attrs) { super(context, attrs); mScroller = new Scroller(context); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int count = getChildCount(); for(int i = 0 ; i < count; i++){ if(i == 0){ getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);//设置每个view的大小 }else{ getChildAt(i).measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); } } setMeasuredDimension(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int left = 0; int width = 0; for(int i = 0 ; i < getChildCount() ; i++){ View childView = getChildAt(i); width = childView.getMeasuredWidth(); childView.layout(left, 0, left+width, childView.getMeasuredHeight()); left += width; } rightWidth = width; } private float mLastMotionX; /** * 返回true,触摸事件被消费,不会传给子控件 * 子控件有点击事件会触发move,up事件,否者只会触发down事件 */ @Override public boolean onInterceptTouchEvent(MotionEvent ev) { float x = ev.getX(); switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mLastMotionX = x; break; case MotionEvent.ACTION_MOVE: int xDiff = (int) Math.abs(x - mLastMotionX);//水平方向移动绝对值 boolean xMove = xDiff > mTouchSlop; //判断水平方向是否移动 if(xMove){ return true; } break; } return false; } float lastX = 0; float lastY = 0; @Override public boolean onTouchEvent(MotionEvent event) { //System.out.println("onTouchEvent = " + event.getAction()); float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: addVelocityTracker(event); lastX = x; lastY = y; break; case MotionEvent.ACTION_MOVE: int xDiff = (int) Math.abs(x - lastX);//水平方向移动绝对值 int yDiff = (int) Math.abs(y - lastY);//垂直方向移动绝对值 if(yDiff > xDiff){//list滑动 //System.out.println("list滑动"); }else{//水平滑动 //System.out.println("水平滑动"); getParent().requestDisallowInterceptTouchEvent(true); addVelocityTracker(event); int deltax = (int) (lastX - x); if(deltax < 0){//向右 if(getScrollX() > 0){ int ScrollX = - getScrollX(); scrollBy(deltax > ScrollX ? deltax : ScrollX, 0); } }else{//向左 if(getScrollX() < rightWidth){ int ScrollX = rightWidth - getScrollX(); scrollBy(deltax > ScrollX ? ScrollX : deltax, 0); } } lastX = x; } break; case MotionEvent.ACTION_UP: eventCancel(); break; case MotionEvent.ACTION_CANCEL: eventCancel(); break; } return true; } private void eventCancel(){ getParent().requestDisallowInterceptTouchEvent(false); int velocityX = getScrollVelocity(); if(velocityX > SNAP_VELOCITY){//向右划 scrollRight(); }else if(velocityX < - SNAP_VELOCITY){//向左划 scrollLeft(); }else{ scrollByDistanceX(); } recycleVelocityTracker(); } /** * 向右划 */ private void scrollRight(){ mScroller.startScroll(getScrollX(), 0, -getScrollX(), 0, 250); postInvalidate(); } /** * 向左划 */ private void scrollLeft(){ mScroller.startScroll(getScrollX(), 0, rightWidth - getScrollX() , 0, 250); postInvalidate(); } /** * 根据滑动距离判断滚动位置 */ private void scrollByDistanceX(){ if(getScrollX() >= rightWidth/2){ scrollLeft(); }else{ scrollRight(); } } /** * 添加速度跟踪 * @param ev */ private void addVelocityTracker(MotionEvent ev){ if(velocityTracker == null){ velocityTracker = VelocityTracker.obtain(); } velocityTracker.addMovement(ev); } /** * 移除速度跟踪 */ private void recycleVelocityTracker(){ if(velocityTracker != null){ velocityTracker.recycle(); velocityTracker = null; } } /** * 获取滑动速度 * @return */ private int getScrollVelocity(){ if(velocityTracker == null){ return 0; }else{ velocityTracker.computeCurrentVelocity(1000); int velocity = (int) velocityTracker.getXVelocity(); return velocity; } } @Override public void computeScroll() {//控制松手后的滑动 super.computeScroll(); if(mScroller.computeScrollOffset()){ scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); } } /** * 恢复原状 */ public void ScorllRest(){ scrollRight(); } public void ScorllRestFast(){ scrollTo(0, 0); } }