android ListView和GridView拖拽移位具体实现及拓展

本文介绍了如何实现Android ListView和GridView的拖拽移位功能,包括限制移动范围、实时交换位置等,旨在提供一种提升用户体验的方法。文中提供了部分关键代码,并展示了实现效果。同时,提到了对GridView的拖拽实现,以及遇到的长按拖拽与点击事件冲突问题。
摘要由CSDN通过智能技术生成

关于ListView拖拽移动位置,想必大家并不陌生,比较不错的软件都用到如此功能了.如:搜狐,网易,百度等,但是相比来说还是百度的用户体验较好,不偏心了,下面看几个示例:

               

首先说一下:拖拽ListView的item就不应该可以任意移动,只应该在ListView所在的范围内,而网易的你看看我都可以移动到状态栏了,虽然你做了处理,但是用户体验我个人感觉不好,在看看百度的,不仅控制了移动范围,更不错的百度的移动起来会时时的换位,看起来相当的形象,所以我认为这样相当的棒.

说明一点,我没有那么有才,我也是看别人代码,然后自己整理下.在这里就简单记载一下.

首先对touch事件的处理,从应用中,我们可以得出,在我们点击后面拖拉图标后,就会创建一个item的影像视图.并且可以移动该影像,而此时的ListView不应该有touch事件.

onInterceptTouchEvent方法.

/***
	 * touch事件拦截 
	 */
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		// 按下
		if (ev.getAction() == MotionEvent.ACTION_DOWN) {
			int x = (int) ev.getX();// 获取相对与ListView的x坐标
			int y = (int) ev.getY();// 获取相应与ListView的y坐标
			dragSrcPosition = dragPosition = pointToPosition(x, y);
			// 无效不进行处理
			if (dragPosition == AdapterView.INVALID_POSITION) {
				return super.onInterceptTouchEvent(ev);
			}

			// 获取当前位置的视图(可见状态)
			ViewGroup itemView = (ViewGroup) getChildAt(dragPosition
					- getFirstVisiblePosition());

			// 获取到的dragPoint其实就是在你点击指定item项中的高度.
			dragPoint = y - itemView.getTop();
			// 这个值是固定的:其实就是ListView这个控件与屏幕最顶部的距离(一般为标题栏+状态栏).
			dragOffset = (int) (ev.getRawY() - y);

			// 获取可拖拽的图标
			View dragger = itemView.findViewById(R.id.iv_drag_list_item_2);

			// x > dragger.getLeft() - 20这句话为了更好的触摸(-20可以省略)
			if (dragger != null && x > dragger.getLeft() - 20) {

				upScrollBounce = getHeight() / 3;// 取得向上滚动的边际,大概为该控件的1/3
				downScrollBounce = getHeight() * 2 / 3;// 取得向下滚动的边际,大概为该控件的2/3

				itemView.setDrawingCacheEnabled(true);// 开启cache.
				Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache());// 根据cache创建一个新的bitmap对象.
				startDrag(bm, y);// 初始化影像
			}
			// return false;
		}

		return super.onInterceptTouchEvent(ev);
	}

这个方法的作用很简单:当我们摁下的如果是可拖拽的图标,那么进行初始化该Item的映像试图.

而在这里如果大家对WindowManager和WindowManager.LayoutParams不熟悉的朋友先去参考下这篇文章,要对WindowManager有一定的了解,简单的会应用.

接下来我们看onTouchEvent事件:

/**
	 * 触摸事件处理
	 */
	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		// item的view不为空,且获取的dragPosition有效
		if (dragImageView != null && dragPosition != INVALID_POSITION) {
			int action = ev.getAction();
			switch (action) {
			case MotionEvent.ACTION_UP:
				int upY = (int) ev.getY();
				stopDrag();
				onDrop(upY);
				break;
			case MotionEvent.ACTION_MOVE:
				int moveY = (int) ev.getY();
				onDrag(moveY);

				break;
			case MotionEvent.ACTION_DOWN:
				break;
			default:
				break;
			}
			return true;// 取消ListView滑动.
		}

		return super.onTouchEvent(ev);
	}
简单说明: 首先在Touch中,我们要进行判断,是否点击的是拖动图标,如果是的话,那么对ACTION_MOVE and ACTION_UP相应事件进行处理,并且返回true or false.作用:取消ListView自身的Touch事件.如果不是的话,执行ListView 本身的Touch事件.

大致就介绍这么多,具体的实现,还是大家看源码吧,我注释的还算清晰,只要大家仔细看的话,一定可以掌握的,为什么这么说呢,技术只有在掌握了情况下才可以进行拓展.

对了,提醒大家要理解这三句话:

getRawX()和getRawY():获得的是相对屏幕的位置.
getX()和getY():获得的永远是相对view的触摸位置 坐标这两个值不会超过view的长度和宽度)。
getLeft getTopgetBottom,
评论 101
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值