GridView 拖拽 排序

http://lipeng88213.iteye.com/blog/1099621

在阅读了上面链接中那位大神提供的源码后 ,让我了解到了拖拽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;  
         }  
           
     }  
 }  



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值