android GridView的拖拽

参考: http://www.cnblogs.com/qianxudetianxia/archive/2011/06/19/2084886.html  

需求:一个可拖拽的gridview 
代码: 

拖拽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>


你可能感兴趣的:(安卓,view)