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
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories