http://lipeng88213.iteye.com/blog/1099621
main activity
在阅读了上面链接中那位大神提供的源码后 ,让我了解到了拖拽guidview 的基本原理。在这里补上我的注释 以防忘记
首先先 继承 gridview 控件 并重写他的 touch event 方法
package com.draggiudviewdemo;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ImageView;
import com.draggiudviewdemo.MainActivity.ImageAdapter;
public abstract class DragGridView extends GridView {
private int dragPosition;//开始拖拽的位置
private int dropPosition;// 结束拖拽的位置
private int dragPointX; //相对于item的x坐标
private int dragPointY; //相对于item的y坐标
private int dragOffsetX;
private int dragOffsetY;
private ImageView dragImageView; //拖动item的preview
private WindowManager windowManager;
private WindowManager.LayoutParams windowParams;
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();
//根据点击位置 获取listview中的某个 position
dragPosition = dropPosition = pointToPosition(x, y);
//判断这个view 在 adapter中是否是invalid_position 不是的话返回
if(dragPosition==AdapterView.INVALID_POSITION){
return super.onInterceptTouchEvent(ev);
}
//获得 listview 中 position 为点击的view
ViewGroup itemView = (ViewGroup)getChildAt(dragPosition - getFirstVisiblePosition());
//得到当前点在item内部的偏移量 即相对于item左上角的坐标
dragPointX = x - itemView.getLeft();
dragPointY = y - itemView.getTop();
//根据相对item的位置获得 相对屏幕的位置 x y
dragOffsetX = (int)(ev.getRawX() - x);
dragOffsetY = (int)(ev.getRawY() - y);
//每次都销毁一次cache,重新生成一个bitmap
itemView.destroyDrawingCache();
itemView.setDrawingCacheEnabled(true);
Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache());
//建立item的缩略图
startDrag(bm,x,y);
return false;
}
return super.onInterceptTouchEvent(ev);
}
/**
* 开始拖拽
* **/
private void startDrag(Bitmap bm, int x, int y) {
stopDrag();
windowParams = new WindowManager.LayoutParams();
System.out.println("X: "+ x +" dragPointX: " + dragPointX +" dragOffsetX: " +dragOffsetX);
windowParams.gravity = Gravity.TOP|Gravity.LEFT;//这个必须加
//得到preview左上角相对于屏幕的坐标
windowParams.x = x - dragPointX + dragOffsetX;
windowParams.y = y - dragPointY + dragOffsetY;
//设置宽和高
windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
windowParams.width = 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.format = PixelFormat.TRANSLUCENT;
windowParams.windowAnimations = 0;
ImageView iv = new ImageView(getContext());
iv.setImageBitmap(bm);
//添加item缩略图到windowmanager中
windowManager = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);//"window"
windowManager.addView(iv, windowParams);
dragImageView = iv;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if(dragImageView!=null && dragPosition!=AdapterView.INVALID_POSITION){
int x = (int)ev.getX();
int y = (int)ev.getY();
switch(ev.getAction()){
case MotionEvent.ACTION_MOVE:
onDrag(x,y);
break;
case MotionEvent.ACTION_UP:
stopDrag();
onDrop(x,y);
break;
}
}
return super.onTouchEvent(ev);
}
private void onDrag(int x, int y) {
//更新缩略图的移动位置
if(dragImageView!=null){
windowParams.alpha = 0.6f;
windowParams.x = x - dragPointX + dragOffsetX;
windowParams.y = y - dragPointY + dragOffsetY;
windowManager.updateViewLayout(dragImageView, windowParams);
}
}
private void onDrop(int x,int y) {
int tempPosition = pointToPosition(x, y);
if(tempPosition!=AdapterView.INVALID_POSITION){
dropPosition = tempPosition;
}
if(dropPosition!=dragPosition){
// ImageAdapter adapter = (ImageAdapter)this.getAdapter();
// adapter.exchange(dragPosition, dropPosition);
doFinishDrag(dropPosition,dragPosition);
}
}
//在结束拖拽以后 remove window
private void stopDrag() {
if(dragImageView!=null){
windowManager.removeView(dragImageView);
dragImageView = null;
}
}
//抽象方法 用于 完成 拖拽以后要执行的 工作
protected abstract void doFinishDrag(int dragPosition,int dropPosition);
}
继承DragGuidView并重写方法
package com.draggiudviewdemo;
import android.content.Context;
import android.util.AttributeSet;
import com.draggiudviewdemo.MainActivity.ImageAdapter;
public class TestDragGridView extends DragGridView {
public TestDragGridView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
@Override
protected void doFinishDrag(int dragPosition, int dropPosition) {
// TODO Auto-generated method stub
ImageAdapter adapter = (ImageAdapter) this.getAdapter();
adapter.exchange(dragPosition, dropPosition);
}
}
main activity
package com.draggiudviewdemo;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends Activity {
private GridView gv;
private List<String> list = new ArrayList<String>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initData();
gv = (GridView)findViewById(R.id.drag_grid);
gv.setAdapter(new ImageAdapter(this));
}
private void initData(){
for(int i=1;i<10;i++){
list.add("grid_"+i);
}
}
public class ImageAdapter extends BaseAdapter{
private Context mContext;
private LayoutInflater lif;
public ImageAdapter(Context c){
mContext = c;
lif = LayoutInflater.from(c);
}
public int getCount() {
return list.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
/**
* 遇到的问题:
* 1、删除错了 会有重复的图片
* 这个是由 remove引起的
* 删除时 我们先删除了小的position
* 比如说 startPosition = 2;endPosition = 3;
* 当我先删startPosition时 这时 删除前position为3的项 已经是position为2了
* 2、数组越界 异常
* 这个是由 add引起的
* 比如说 startPosition = 8;endPosition = 7;
* 一共gridview有9个元素 也就是说8 已经是最大的了
* 当删除完后 你先增加爱 startposition时 就会异常了
* 3、preview问题
* 当我拖拽互换几次后 机会出现 当前的图片 显示的是另一个图片的preview
*
* 得调用 destroyDrawingCache
* @param startPosition
* @param endPosition
*/
public void exchange(int startPosition, int endPosition){
//比较一下 使startPosition永远小于endPosition的值 解决问题1 ,2
if(startPosition > endPosition){
int temp = endPosition;
endPosition = startPosition;
startPosition = temp;
}
Object endObject = getItem(endPosition);
Object startObject = getItem(startPosition);
//list.remove(endPosition);
//list.remove(startPosition);
list.set(startPosition,(String)endObject);
list.set(endPosition,(String)startObject);
notifyDataSetChanged();
}
public View getView(int position, View convertView, ViewGroup parent) {
//ImageView iv;
if(convertView==null){
convertView = lif.inflate(R.layout.grid_item, null);
// iv = new ImageView(mContext);
// try{
// Field f = (Field)R.drawable.class.getDeclaredField(list.get(position));
// int i = f.getInt(R.drawable.class);
// iv.setImageResource(i);
// }catch(Exception e){
// e.printStackTrace();
// }
}
try {
ImageView iv = (ImageView)convertView.findViewById(R.id.image);
if(position>4){
iv.setImageResource(R.drawable.face217);
}else{
iv.setImageResource(R.drawable.face218);
}
TextView tv = (TextView) convertView.findViewById(R.id.mytext);
tv.setText(list.get(position));
} catch (Exception e) {
e.printStackTrace();
}
// else{
// iv = (ImageView)convertView;
// }
System.out.println("here"+position);
return convertView;
}
}
}