android ListView和GridView拖拽移位实现代码

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

文章正文

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

首先说一下:拖拽ListView的item就不应该可以任意移动,只应该在ListView所在的范围内,而网易的你看看我都可以移动到状态栏了,虽然你做了处理,但是用户体验我个人感觉不好,在看看百度的,不仅控制了移动范围,更不错的百度的移动起来会时时的换位,看起来相当的形象,所以我认为这样相当的棒.
说明一点,我没有那么有才,我也是看别人代码,然后自己整理下.在这里就简单记载一下.
首先对touch事件的处理,从应用中,我们可以得出,在我们点击后面拖拉图标后,就会创建一个item的影像视图.并且可以移动该影像,而此时的ListView不应该有touch事件.
onInterceptTouchEvent方法.
[java]

下载源码.
好了还是我们来观看下效果吧.

怎么样,这个效果看起来要比上面那个效果更人性化点吧,我的操作或许有点快,不信的话,你自己手机体验一下吧.
关于ListView拖拽就说到这里,如有不足请大家自己创新.

下面我们接着对GridView的拖拽简单说明.因为这些在项目中我们都会用到,所以既然做到就做全面点吧.好了大家接着往下看吧.
首先说明,原理一样,都是拖动映像,记录拖动位置,然后调用notifyDataSetChanged更新UI.
而GridView不同的是你要根据x,y值共同获取点击的position和移动至的position,而ListView因为不涉及x坐标.
嗯,最初的原始移动我就不给大家展示了,效果也不是很友好,我直接展示时时更新的那种方法.效果类是与上面那个时时更新ListView一样。
原理也一样.下面我们直接看代码吧.
[java]

复制代码 代码如下:

package com.jj.draggrid;

import java.util.logging.Handler;

import com.jj.draggrid.MainActivity.DragGridAdapter;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.Toast;

/***
* 自定义拖拽GridView
*
* @author zhangjia
*
*/

public class DragGridView extends GridView {

private WindowManager windowManager;// windows窗口控制类
private WindowManager.LayoutParams windowParams;// 用于控制拖拽项的显示的参数

private int scaledTouchSlop;// 判断滑动的一个距离,scroll的时候会用到(24)

private ImageView dragImageView;// 被拖拽的项(item),其实就是一个ImageView
private int dragSrcPosition;// 手指拖动项原始在列表中的位置
private int dragPosition;// 手指点击准备拖动的时候,当前拖动项在列表中的位置.

private int dragPointX;// 在当前数据项中的位置
private int dragPointY;// 在当前数据项中的位置
private int dragOffsetX;// 当前视图和屏幕的距离(这里只使用了x方向上)
private int dragOffsetY;// 当前视图和屏幕的距离(这里只使用了y方向上)

private int upScrollBounce;// 拖动的时候,开始向上滚动的边界
private int downScrollBounce;// 拖动的时候,开始向下滚动的边界

private int temChangId;// 临时交换id

private boolean isDoTouch = false;// touch是否可用

private boolean isHide = false;// 是否隐藏

private Handler handler;

public void setDoTouch(boolean isDoTouch) {
this.isDoTouch = isDoTouch;
}

public DragGridView(Context context, AttributeSet attrs) {
super(context, attrs);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {

if (ev.getAction() == MotionEvent.ACTION_DOWN) {
int x = (int) ev.getX();
int y = (int) ev.getY();

temChangId = dragSrcPosition = dragPosition = pointToPosition(x, y);

if (dragPosition == AdapterView.INVALID_POSITION) {
return super.onInterceptTouchEvent(ev);
}

ViewGroup itemView = (ViewGroup) getChildAt(dragPosition
- getFirstVisiblePosition());

dragPointX = x - itemView.getLeft();
dragPointY = y - itemView.getTop();
dragOffsetX = (int) (ev.getRawX() - x);
dragOffsetY = (int) (ev.getRawY() - y);

View dragger = itemView.findViewById(R.id.drag_grid_item);

/***
* 判断是否选中拖动图标
*/
if (dragger != null && dragPointX > dragger.getLeft()
&& dragPointX < dragger.getRight()
&& dragPointY > dragger.getTop()
&& dragPointY < dragger.getBottom() + 20) {

upScrollBounce = getHeight() / 4;
downScrollBounce = getHeight() * 3 / 4;

itemView.setDrawingCacheEnabled(true);
Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache());
startDrag(bm, x, y);// 初始话映像

dragger.setVisibility(View.INVISIBLE);// 隐藏该项.
}
}

return super.onInterceptTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {

if (dragImageView != null && dragPosition != INVALID_POSITION
&& isDoTouch) {
int action = ev.getAction();
switch (action) {
/***
*
*/
case MotionEvent.ACTION_UP:
int upX = (int) ev.getX();
int upY = (int) ev.getY();
stopDrag();// 删除映像
onDrop(upX, upY);// 松开
// isDoTouch = false;
break;
/***
* 拖拽item
*
*/
case MotionEvent.ACTION_MOVE:
int moveX = (int) ev.getX();
int moveY = (int) ev.getY();
onDrag(moveX, moveY);// 拖拽
break;
case MotionEvent.ACTION_DOWN:
int downX = (int) ev.getX();
int downY = (int) ev.getY();
onHide(downX, downY);// 隐藏该项
break;
default:
break;
}
return true;
}

return super.onTouchEvent(ev);
}

/**
* 准备拖动,初始化拖动项的图像
*
* @param bm
* @param y
*/
public void startDrag(Bitmap bm, int x, int y) {

windowParams = new WindowManager.LayoutParams();
windowParams.gravity = Gravity.TOP | Gravity.LEFT;
windowParams.x = x - dragPointX + dragOffsetX;
windowParams.y = y - dragPointY + dragOffsetY;
windowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;

windowParams.windowAnimations = 0;

ImageView imageView = new ImageView(getContext());
imageView.setImageBitmap(bm);
windowManager = (WindowManager) getContext().getSystemService("window");
windowManager.addView(imageView, windowParams);
dragImageView = imageView;

}

/***
* 拖动时时change
*/
private void onChange(int x, int y) {
// 获取适配器
DragGridAdapter adapter = (DragGridAdapter) getAdapter();
// 数据交换
if (dragPosition < getAdapter().getCount()) {
// 不相等的情况下要进行换位,相等的情况下说明正在移动
if (dragPosition != temChangId) {
adapter.update(temChangId, dragPosition);// 进行换位
temChangId = dragPosition;// 将点击最初所在位置position付给临时的,用于判断是否换位.
}

}

// 为了避免滑动到分割线的时候,返回-1的问题
int tempPosition = pointToPosition(x, y);
if (tempPosition != INVALID_POSITION) {
dragPosition = tempPosition;
}

}

/***
* 拖动执行,在Move方法中执行
*
* @param x
* @param y
*/
public void onDrag(int x, int y) {
// 移动
if (dragImageView != null) {
windowParams.alpha = 0.8f;
windowParams.x = x - dragPointX + dragOffsetX;
windowParams.y = y - dragPointY + dragOffsetY;
windowManager.updateViewLayout(dragImageView, windowParams);
}

onChange(x, y);// 时时交换

// 滚动
if (y < upScrollBounce || y > downScrollBounce) {
// 使用setSelection来实现滚动
setSelection(dragPosition);
}

}

/***
* 隐藏该选项
*/
private void onHide(int x, int y) {
// 获取适配器
DragGridAdapter adapter = (DragGridAdapter) getAdapter();
// 为了避免滑动到分割线的时候,返回-1的问题
int tempPosition = pointToPosition(x, y);
if (tempPosition != INVALID_POSITION) {
dragPosition = tempPosition;
}
adapter.setIsHidePosition(dragPosition);

}

/**
* 停止拖动,删除影像
*/
public void stopDrag() {
if (dragImageView != null) {
windowManager.removeView(dragImageView);
dragImageView = null;
}
}

/***
* 拖动放下的时候
*
* @param x
* @param y
*/
public void onDrop(int x, int y) {

DragGridAdapter adapter = (DragGridAdapter) getAdapter();
adapter.setIsHidePosition(-1);// 不进行隐藏

}

}


代码注释

作者:喵哥笔记

IDC笔记

学的不仅是技术,更是梦想!

© 2020 IDC笔记 . | 备案号:辽ICP备18000516号