ViewDragHelper:
在侧滑菜单中,都会用到一个类: ViewDragHelper.v4包中的类,2013年 google i/o大会上提出,用来解决控件拖动的问题,简化android中手势滑动操作。
v4包中的DrawerLayout和SlidingPaneLayout内部都使用到了ViewDragHelper。
在自定义中写一个 ViewDragHelper 的实例( ViewDragHelper.create(this,mCallBack);),传入一个回调对象 new CallBack();在 CallBack 中一般要重写这几个方法:
在侧滑菜单中,都会用到一个类: ViewDragHelper.v4包中的类,2013年 google i/o大会上提出,用来解决控件拖动的问题,简化android中手势滑动操作。
v4包中的DrawerLayout和SlidingPaneLayout内部都使用到了ViewDragHelper。
在自定义中写一个 ViewDragHelper 的实例( ViewDragHelper.create(this,mCallBack);),传入一个回调对象 new CallBack();在 CallBack 中一般要重写这几个方法:
1.tryCaptureView: 是否要捕获(capture)子控件, 返回true则表示捕获,捕获了则可以实现拖动
2.clampViewPositionHorizontal:设置控件水平方向将要显示的位置,以控件的左边界来确定位置(clamp:固定住)
3.onViewPositionChanged:当子控件位置发生改变时,调用.
4.getViewHorizontalDragRange:返回子控件水平方向拖动的最大范围(Range: 范围),注意:实际上并不会真正限制子控件拖动的范围.
作用:
(a) 当子控件消费事件时,此方法需要返回大于0的值,子控件才可以实现拖动, 默认返回0则不可以拖动
(b) 用来确定拖动结束后动画执行时长(了解)
如果想要真正控制子控件拖动的范围,可以在clampViewPositionHorizontal方法中设置:
5.onViewReleased:拖动控件时移动,松开手后将调用该方法.
(a) 当子控件消费事件时,此方法需要返回大于0的值,子控件才可以实现拖动, 默认返回0则不可以拖动
(b) 用来确定拖动结束后动画执行时长(了解)
如果想要真正控制子控件拖动的范围,可以在clampViewPositionHorizontal方法中设置:
5.onViewReleased:拖动控件时移动,松开手后将调用该方法.
在自定义控件中一般还要重写的方法:
1.onInterceptTouchEvent:拦截事件.一般交给 ViewDragHelper 对象决定是否拦截:return mViewDragHelper.shouldInterceptTouchEvent(ev);
2.onTouchEvent:把触摸事件交给ViewDragHelper处理.mViewDragHelper.processTouchEvent(event);而且要注意的是结果要 return true,
把事件给消费掉.因为 点击,滑动,抬起 这三个动作是一组事件,返回 true ,把该事件消费掉才能把该整组事件执行完;如果返回 false,没有消费该事件
则只会执行 点击 这一事件,然后传递给下一个事件, 滑动 , 抬起 将不会执行.
ViewDragHandler 的平滑移动:mViewDragHelper.smoothSlideViewTo(viewChild,width,heigth);
然后要刷新动画:ViewCompat.postInvalidateOnAnimation(this);然后重写 computeScroll方法.在该方法里面判断 mViewDragHandler 是不是
继续设置动作,参数为 true,表示继续,然后再刷新.
因为 ViewCompat 调用 postInvalidateOnAnimation(this) 方法,其实在里面走的流程为 invalidate -> onDraw() -> computeScroll()
例子:
private void open(){
mViewDragHelper.smoothSlideViewTo(mContentView,-mMenuWidth,0);
// 刷新界面: invalidate -> onDraw() -> computeScroll()
ViewCompat.postInvalidateOnAnimation(this);
}
@Override
public void computeScroll() {
if(mViewDragHelper.continueSettling(true)){
ViewCompat.postInvalidateOnAnimation(this);
}
}