当前位置: 代码迷 >> Android >> Android 组合滑动控件ListView滑动删除
  详细解决方案

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

热度:25   发布时间:2016-04-28 02:55:39.0
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一个成熟的


项目源码





1楼bigkai229昨天 17:01
前排,沙发。哈哈哈,写的那么流弊,
  相关解决方案