- CompoundButton 源码分析
- LinearLayout 源码分析
- SearchView 源码解析
- LruCache 源码解析
- ViewDragHelper 源码解析
- BottomSheets 源码解析
- Media Player 源码分析
- NavigationView 源码解析
- Service 源码解析
- Binder 源码分析
- Android 应用 Preference 相关及源码浅析 SharePreferences 篇
- ScrollView 源码解析
- Handler 源码解析
- NestedScrollView 源码解析
- SQLiteOpenHelper/SQLiteDatabase/Cursor 源码解析
- Bundle 源码解析
- LocalBroadcastManager 源码解析
- Toast 源码解析
- TextInputLayout
- LayoutInflater 和 LayoutInflaterCompat 源码解析
- TextView 源码解析
- NestedScrolling 事件机制源码解析
- ViewGroup 源码解析
- StaticLayout 源码分析
- AtomicFile 源码解析
- AtomicFile 源码解析
- Spannable 源码分析
- Notification 之 Android 5.0 实现原理
- CoordinatorLayout 源码分析
- Scroller 源码解析
- SwipeRefreshLayout 源码分析
- FloatingActionButton 源码解析
- AsyncTask 源码分析
- TabLayout 源码解析
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
2. 使用方法
我们这里就以 翔总的这篇文章 中的例子来介绍一下 ViewDragHelper
的使用.另外,本文中的 demo 可以在 这里找到
首先我们创建一个 DragLayout
类并继承自 LinearLayout
,然后我们准备在 DragLayout
放置三个 View
第一个用来被我们拖动然后停止在松手的位置,第二个可以被我们拖动,松手的时候滑动到指定位置,第三个只可以通过触摸边缘来进行拖动,
public class DragLayout extends LinearLayout { private ViewDragHelper mDragger; private View mDragView; private View mAutoBackView; private View mEdgeTrackerView; private Point mAutoBackOriginPos = new Point(); public DragLayout(Context context) { this(context, null); } public DragLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public DragLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initViewDragHelper(); } private void initViewDragHelper() { mDragger = ViewDragHelper.create(this,myCallback); mDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_ALL); } ViewDragHelper.Callback myCallback = new ViewDragHelper.Callback() { @Override //child 为当前触摸区域下的 View,如果返回 true,就可以拖拽。 public boolean tryCaptureView(View child, int pointerId) { return child == mDragView || child == mAutoBackView; } //松手时的回调 @Override public void onViewReleased(View releasedChild, float xvel, float yvel) { if (releasedChild == mAutoBackView) { mDragger.settleCapturedViewAt(mAutoBackOriginPos.x, mAutoBackOriginPos.y); invalidate(); } } //边缘触摸开始时的回调 @Override public void onEdgeDragStarted(int edgeFlags, int pointerId) { mDragger.captureChildView(mEdgeTrackerView, pointerId); } //获取水平方向允许拖拽的区域,这里是父布局的宽-子控件的宽 @Override public int getViewHorizontalDragRange(View child) { return getMeasuredWidth() - child.getMeasuredWidth(); } //获取垂直方向允许拖拽的范围 @Override public int getViewVerticalDragRange(View child) { return getMeasuredHeight() - child.getMeasuredHeight(); } //left 为 child 即将移动到的水平位置的值,但是返回值会最终决定移动到的值 //这里直接返回了 left @Override public int clampViewPositionHorizontal(View child, int left, int dx) { return left; } //同上只是这里是垂直方向 @Override public int clampViewPositionVertical(View child, int top, int dy) { return top; } }; @Override public void computeScroll() { if (mDragger.continueSettling(true)) { invalidate(); } } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return mDragger.shouldInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { mDragger.processTouchEvent(event); return true; } @Override protected void onFinishInflate() { super.onFinishInflate(); mDragView = getChildAt(0); mAutoBackView = getChildAt(1); mEdgeTrackerView = getChildAt(2); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); mAutoBackOriginPos.x = mAutoBackView.getLeft(); mAutoBackOriginPos.y = mAutoBackView.getTop(); } }
- 我们首先在构造方法里传入了当前类的对象和我们定义的
ViewDragHelper.Callback
对象初始化了我们的ViewDragHelper
,然后我们希望所有的边缘触摸都能触发mEdgeTrackerView
的拖动,所以我们紧接着调用了mDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_ALL);
方法。 - 在我们定义的
Callback
中,有多个回调方法,每个回调方法都有它的作用,在代码里注释比较清楚了,我们下面也会解析每一个Callback
中回调方法的作用。 - 第三步我们需要在
onInterceptTouchEvent()
方法和onTouchEvent()
将事件委托给ViewDragHelper
去处理,这样ViewDragHelper
才能根据响应的事件并回调我们自己编写的Callback
接口来进行响应的处理, - 由于
ViewDragHelper
中的滑动是交给Srcoller
类来处理的所以这里我们要重写computeScroll()
方法,配合Scroller
完成滚动动画。 - 最后在
onFinishInflate()
里获取到我们的View
对象即可。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论