在android的开发包android.support.v4.widget中有一个ViewDragHelper类。这个类的作用是帮助我们处理View的拖拽滑动。在一个ViewGroup类的内部定义一个ViewDragHelper,并且把onInterceptTouchEvent()和onTouchEvent()事件交给这个类去处理,这样也就免去了烦琐的事件处理判断。
1.创建实例
1 public static ViewDragHelper create (ViewGroup forParent, float sensitivity, ViewDragHelper.Callback cb)
ViewDragHelper提供了这个静态方法来创建一个实例。forParent表示当前的ViewGroup,ViewDragHelper一般定义在ViewGroup中,这样这个参数也就this。 sensitivity表示敏感度,值越大越敏感,越能快速的检测到滑动,默认的正常值是1.0f。ViewDragHelper.Callback这个抽象类是核心的部分,在这个类中定义了所有的事件的处理。
2.状态
STATE_DRAGGING: view正处在被拖动的状态
STATE_IDLE: view没有被拖动或者动画已经结束的状态
STATE_SETTLING:指定了view的确定位置的时候,view处于这种状态
下面用一个例子来演示这个类的使用:
1 package com.example.ubuntu.viewdragermotion; 2 3 import android.content.Context; 4 import android.support.v4.view.MotionEventCompat; 5 import android.support.v4.widget.ViewDragHelper; 6 import android.util.AttributeSet; 7 import android.view.MotionEvent; 8 import android.view.View; 9 import android.view.ViewGroup; 10 import android.widget.LinearLayout; 11 12 /** 13 * Created by ubuntu on 15-12-1. 14 */ 15 public class DragerMotionLayout extends LinearLayout { 16 private View mChild_01; 17 private ViewDragHelper mDragHelper = null; 18 //设置ViewDragHelper的回调方法 19 private ViewDragHelper.Callback mCallBack = new ViewDragHelper.Callback() { 20 @Override 21 public boolean tryCaptureView(View child, int pointerId) { 22 //捕获view,被捕获之后,可以跟随手指的操作 23 return child == mChild_01; 24 } 25 26 @Override 27 public int clampViewPositionHorizontal(View child, int left, int dx) { 28 //当用手拖动view的时候,设置view的水平方向上滑动距离 29 final int leftPadding = child.getPaddingLeft(); 30 final int rightPadding = ((ViewGroup) child.getParent()).getWidth() - child.getWidth(); 31 return Math.min(rightPadding, Math.max(left, leftPadding)); 32 } 33 34 @Override 35 public int clampViewPositionVertical(View child, int top, int dy) { 36 //当用手拖动view的时候,设置view的垂直方向上滑动距离 37 final int topPadding = child.getPaddingTop(); 38 final int bottomPadding = ((ViewGroup) child.getParent()).getHeight() - child.getHeight(); 39 return Math.min(bottomPadding, Math.max(top,topPadding)); 40 } 41 42 @Override 43 public void onEdgeDragStarted(int edgeFlags, int pointerId) { 44 //边缘滑动的时候,捕获view 45 mDragHelper.captureChildView(mChild_01, pointerId); 46 } 47 48 @Override 49 public void onViewReleased(View releasedChild, float xvel, float yvel) { 50 //设置当手指离开的时候,view应该设置的位置,调用这个方法的时候,必须保证 51 //computeScroll()方法中使用的是ViewDragHelper.continueSettling(true)方法接管 52 mDragHelper.settleCapturedViewAt(0,0); 53 invalidate(); 54 } 55 }; 56 57 public DragerMotionLayout(Context context) { 58 this(context, null); 59 } 60 61 public DragerMotionLayout(Context context, AttributeSet attrs) { 62 this(context, attrs, 0); 63 } 64 65 public DragerMotionLayout(Context context, AttributeSet attrs, int defStyleAttr) { 66 super(context, attrs, defStyleAttr); 67 init(); 68 } 69 70 @Override 71 protected void onFinishInflate() { 72 super.onFinishInflate(); 73 mChild_01 = this.getChildAt(0); 74 } 75 76 private void init() { 77 //初始化ViewDragHelper 78 mDragHelper = ViewDragHelper.create(this, 1.0f, mCallBack); 79 //使监听左边的边缘滑动 80 mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT); 81 } 82 83 @Override 84 public boolean onInterceptTouchEvent(MotionEvent ev) { 85 int action = MotionEventCompat.getActionMasked(ev); 86 if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { 87 mDragHelper.cancel(); 88 return false; 89 } 90 //ViewDragHelper接管事件的拦截 91 return mDragHelper.shouldInterceptTouchEvent(ev); 92 } 93 94 95 @Override 96 public boolean onTouchEvent(MotionEvent event) { 97 //ViewDragHelper接管事件的处理 98 mDragHelper.processTouchEvent(event); 99 return true; 100 } 101 102 @Override 103 public void computeScroll() { 104 //如果view处于STATE_SETTLING状态下,使用该方法接管 105 if(mDragHelper.continueSettling(true)){ 106 invalidate(); 107 } 108 } 109 }
时间: 2024-11-16 02:31:23