Android 结合滑动控件ListView滑动删除

来源:互联网 发布:淘宝 买入职体检报告 编辑:程序博客网 时间:2024/06/07 16:37

一转眼就15年了,希望大家15年升职加薪走上人生巅峰

这篇博客是结合上一篇ListView滑动删除之Viewgroup打造滑动控件(修正版)博客所完成的,先上个效果图吧.


其实实现起来并不复杂

1,解决滑动冲突

因为我们的自定义滑动控件和ListView本身的滑动事件会产生各种冲突,所以我们可以自定义ListView并重写onInterceptTouchEvent方法。

我们先来了解一下android事件的分发,当用户触摸屏幕时会先去调用ViewGroup的dispatchTouchEvent方法。

而在dispathTouchEvent方法中又会调用onInterceptTouchEvent方法,这个方法主要的目的就是用来拦截用户的操作,具体的分发机制详情可以看郭神的博客 Android事件分发机制完全解析,带你从源码的角度彻底理解(下)。

我们这里就先知道如果这个方法返回false则是touch事件全部由子view完成就可以,看看代码。

/** * 判断是否拦截事件 */public boolean onInterceptTouchEvent(MotionEvent ev) {float lastX = ev.getX();float lastY = ev.getY();switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:mFirstX = lastX;mFirstY = lastY;int motionPosition = pointToPosition((int) mFirstX, (int) mFirstY);if (motionPosition >= 0) {currentItemView = getChildAt(motionPosition- getFirstVisiblePosition());mySwipeItem = (MySwipeItem) currentItemView.findViewById(R.id.myitem);}break;case MotionEvent.ACTION_MOVE:float dx = lastX - mFirstX;float dy = lastY - mFirstY;Log.d("TAG", "DX:" + dx);if (Math.abs(dx) >= 5 && Math.abs(dy) >= 5) {return false;}if (Math.abs(dx) < 5 && Math.abs(dx) > 0) {mySwipeItem.toOff();}break;default:break;}return super.onInterceptTouchEvent(ev);}

在这里我就是在move的时候做判断,如果条件满足我们就认为用户是在进行横向滑动操作,而在down的时候获取到listview的子view,当move条件不满足开始进行纵向滑动的时候使控件关闭。

2,使用回调接口

我们的效果为如果滑开了这个控件下次再点击除button以外的地方就关闭滑动控件,我们可以使用接口回调来实现这个效果

public interface OnScrollState {public void scrollView();public void scrollOn(View view);}public void setOnScrollState(OnScrollState onScrollState) {this.mOnScrollState = onScrollState;}
自定义了一个接口然后在touch的时候进行判断

@Overridepublic boolean onTouchEvent(MotionEvent event) {int scrollX = getScrollX();int x = (int) event.getX();switch (event.getAction()) {case MotionEvent.ACTION_DOWN: {if (!mScroller.isFinished()) {mScroller.abortAnimation();}if (mOnScrollState != null) {mOnScrollState.scrollView();}break;}case MotionEvent.ACTION_MOVE: {int deltaX = x - lastX;// 计算滑动终点是否合法,防止滑动越界int newScrollX = scrollX - deltaX;if (deltaX != 0) {if (newScrollX < 0) {newScrollX = 0;} else if (newScrollX > mMaxDistancex) {newScrollX = mMaxDistancex;}this.scrollTo(newScrollX, 0);}break;}case MotionEvent.ACTION_UP: {int newScrollX = 0;// 这里做了下判断,当松开手的时候,会自动向两边滑动,具体向哪边滑,要看当前所处的位置if (scrollX > mMaxDistancex / 2) {newScrollX = mMaxDistancex;}// 慢慢滑向终点this.smoothScrollTo(newScrollX, 0);if (mOnScrollState != null && newScrollX == mMaxDistancex) {mOnScrollState.scrollOn(this);}break;}}lastX = x;return true;}
在Main中进行调用控件的关闭方法

@Overridepublic void scrollView() {if (mLastItem != null) {mLastItem.toOff();}}@Overridepublic void scrollOn(View view) {mLastItem = (MySwipeItem) view;}

3,缺点

很简单就实现了滑动效果不是么。。。。但是我们会发现我们自己的listview的onItemClick方法不起作用了!!,因为我们重写了onInterceptTouchEvent方法,但是我们的滑动控件中的textView以及button还是可以用onclick的,所以还有一种listview的滑动删除方法高仿微信对话列表滑动删除效果。

4,后记

不要问我为什么自己不写一个完美的,我才不会说是因为我写不出来又犯懒了。。。。新手可以学习借鉴了解一下android的分发机制,但要是真的要用到项目中,我还是建议去Github上down一个成熟的


项目源码





0 0
原创粉丝点击