您的位置:首页 > 移动开发 > Android开发

ViewDragHelper实现右划关闭Activity

2015-11-04 18:06 330 查看


这段时间学习了
ViewDragHelper
的使用,觉得挺牛逼的,使用起来也特别的方便。它可以方便的让我们处理触摸事件,是否分发,是否处理,一句话,使用它你可以忽略touch过程中的一些细节了!!

先看看
ViewDragHelper
的创建吧!

ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() {}
通过一个
create
的静态方法就可以获取到ViewDragHelper的一个实体。

这里需要传入一个
Callback
;

接下来重点说说这个
Callback
;它里面有很多的方法。。



搂一眼之后还是先来看看
ViewDragHelper
的几个重要的方法。

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return mViewDragHelper.shouldInterceptTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
mViewDragHelper.processTouchEvent(event);
return true;
//这里一定要记得返回true;
}


通过这两个方法的设定,那么我们的触摸事件就移交给
ViewDragHelper
了,让它帮我处理是否要中断传播和处理触摸相关的事件。

获取到填充的布局:

@Override
protected void onFinishInflate() {
super.onFinishInflate();
//该布局中应该只有一个子布局,所有的其他布局填充到这个子布局中。
mContentView = getChildAt(0);
}


onLayout()
的方法中得到view的宽度!!

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
mContentWidth = mContentView.getWidth();
}


接下来看看
Callback
的相关代码:

@Override
public boolean tryCaptureView(View child, int pointerId) {
return child == mContentView;//只有mContentView可以移动
}

@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
mMoveLeft = left;
if (mCallBack != null) {
mCallBack.onPositionChanged(left, top, dx, dy);
}
if (isClose && (left == mContentWidth)) {
if (mCallBack != null) {
mCallBack.onFinish();
}
activity.finish();

}
}

@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
if (mMoveLeft >= (mContentWidth / 2)) {
//滑动超过屏幕的一半,那么就可以判断为true了!
isClose = true;
mViewDragHelper.settleCapturedViewAt(mContentWidth, releasedChild.getTop());
} else {
mViewDragHelper.settleCapturedViewAt(0, releasedChild.getTop());
}
invalidate();
}
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {

return left;
}
@Override
public int getViewHorizontalDragRange(View child) {
//一定要重写这个方法,返回>0的值,不然当子View可以消耗触摸事件时就会无法移动。
return mContentWidth;
}


tryCaptureView()
的方法就是返回是否可以操作。

onViewPositionChanged()
就是位置发生变化时的相关回调。

onViewReleased()
这个就是当我们抬起手,释放的操作时。我们的相关判断其实就是在这个方法中完成的。如果移动的距离大于等于屏幕宽度的一半,那么在释放的时候我们就finish当前的Activity

clampViewPositionHorizontal()
返回建议的left就好!

getViewHorizontalDragRange()
如果我们滑动的控件可以消费触摸事件,那么为了可以成功的移动它,我们必须得重写这个方法,返回值>0就好!

最后复写一下

@Override
public void computeScroll() {
super.computeScroll();
if (mViewDragHelper.continueSettling(true)) {
invalidate();
}
}


到这里就完了哇??哈哈,还没有呢!因为你会发现这样你弄的的确可以滑动了,但是看不到下面的Activity啊!!这是什么鬼??最后还得给Activity设置为透明的背景。

<style name="AppTheme1" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
</style>


配置这两个属性,基本上就大功告成了!!

nono..是不是Activity划出去之后还有屏幕一闪一闪的情况?那可能是因为Activity默认的动画效果。

所以在上面
finish()
是应该再设置一下(这两句话的位置不能反了!):

this.finish();
this.overridePendingTransition(0, 0);//取消Activity的动画。//取消Activity的动画。


最后的最后,如果你想让Activity的开启动画变成是从左到右的,那么也设置一下就好:

对应的就是:

activity_in

<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator"
android:fromXDelta="100%"  android:toXDelta="0"
android:duration="@android:integer/config_mediumAnimTime"
>
</translate>


activity_out

<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator"
android:fromXDelta="0"  android:toXDelta="-100%"
android:duration="@android:integer/config_mediumAnimTime"
>
</translate>


更新:

之前的代码使用的话,会出现Activity左右都能滑动。

@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
//这样的话,页面就只能向右滑动了!
return Math.min(mContentWidth, Math.max(left, 0));
}


如果需要实现边界触摸才有效果的话:需要做如下修改:

1.实现边界滑动的回调,在里面处理对应的view!

@Override
public void onEdgeDragStarted(int edgeFlags, int pointerId) {
super.onEdgeDragStarted(edgeFlags, pointerId);
//在里面处理我们需要实现边界滑动有效的view
mViewDragHelper.captureChildView(mContentView, pointerId);
}


2.设置边界滑动可用:

mViewDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);


这里当然是左边有效啦!

3.最后需要将之前的
tryCaptureView()
的方法中的
mContentView
的相关逻辑注释掉!

Demo下载

as直接导入module!

GitHub
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android