拖拽view:
package com.lp; import com.lp.MainActivity.ImageAdapter; 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; public 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(); dragPosition = dropPosition = pointToPosition(x, y); System.out.println(dragPosition); if(dragPosition==AdapterView.INVALID_POSITION){ return super.onInterceptTouchEvent(ev); } ViewGroup itemView = (ViewGroup)getChildAt(dragPosition - getFirstVisiblePosition()); //得到当前点在item内部的偏移量 即相对于item左上角的坐标 dragPointX = x - itemView.getLeft(); dragPointY = y - itemView.getTop(); dragOffsetX = (int)(ev.getRawX() - x); dragOffsetY = (int)(ev.getRawY() - y); //解决问题3 //每次都销毁一次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); 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){ System.out.println("dragPosition: "+dragPosition+" dropPosition: "+dropPosition); ImageAdapter adapter = (ImageAdapter)this.getAdapter(); adapter.exchange(dragPosition, dropPosition); //解决问题3 /* ViewGroup itemView1 = (ViewGroup)getChildAt(dragPosition - getFirstVisiblePosition()); ViewGroup itemView2 = (ViewGroup)getChildAt(dropPosition - getFirstVisiblePosition()); itemView1.destroyDrawingCache(); itemView2.destroyDrawingCache(); */ } } private void stopDrag() { if(dragImageView!=null){ windowManager.removeView(dragImageView); dragImageView = null; } } }
package com.lp; import android.app.Activity; import android.content.Context; import android.os.Bundle; 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 java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; 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); System.out.println(startPosition + "========"+endPosition); 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 { Field f = (Field)R.drawable.class.getDeclaredField(list.get(position)); int i = f.getInt(R.drawable.class); ImageView iv = (ImageView)convertView.findViewById(R.id.image); iv.setImageResource(i); } catch (Exception e) { e.printStackTrace(); } // else{ // iv = (ImageView)convertView; // } return convertView; } } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.lp.DragGridView android:id="@+id/drag_grid" android:layout_width="fill_parent" android:layout_height="fill_parent" android:cacheColorHint="#00000000" android:numColumns="3" android:stretchMode="columnWidth" android:verticalSpacing="5dip" android:horizontalSpacing="20dip" android:background="#ffffff"/> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView android:id="@+id/image" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>