- 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对象即可。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论