首页 > 代码库 > Android 结合滑动控件ListView滑动删除
Android 结合滑动控件ListView滑动删除
一转眼就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的时候进行判断
@Override public 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中进行调用控件的关闭方法
@Override public void scrollView() { if (mLastItem != null) { mLastItem.toOff(); } } @Override public void scrollOn(View view) { mLastItem = (MySwipeItem) view; }
3,缺点
很简单就实现了滑动效果不是么。。。。但是我们会发现我们自己的listview的onItemClick方法不起作用了!!,因为我们重写了onInterceptTouchEvent方法,但是我们的滑动控件中的textView以及button还是可以用onclick的,所以还有一种listview的滑动删除方法高仿微信对话列表滑动删除效果。
4,后记
不要问我为什么自己不写一个完美的,我才不会说是因为我写不出来又犯懒了。。。。新手可以学习借鉴了解一下android的分发机制,但要是真的要用到项目中,我还是建议去Github上down一个成熟的
项目源码
Android 结合滑动控件ListView滑动删除