自定义GridView并且实现拖拽

写在前面的话

         本篇blog实现了GridView的拖拽功能。方法和上一篇自定义ListView实现拖拽ListItem项交换位置一个原理。只是在交换位置上记录了X轴的相关坐标,计算了X轴的相关变量。

 

 

实现效果图如下


说明:

本篇给出实现代码,但是不做任何说明。如需了解请看上一篇blog:

自定义ListView实现拖拽ListItem项交换位置

 

文件代码:

 

1、MainActivity.java

package com.jay.draggridview;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;

public class MainActivity extends Activity {

	
	private static List<String> list = null;
	//自定义适配器
    private DragGridAdapter adapter = null;

	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//初始化数据
		initData();
		
		 //后面用到的自定义GridView
        DragGridView dragGridView = (DragGridView)findViewById(R.id.drag_grid);
        adapter = new DragGridAdapter(this, list);
        dragGridView.setAdapter(adapter);
	}
	
	
	public void initData(){
		list = new ArrayList<String>();
		for(int i= 0 ; i < 12 ; i++){
			list.add("grid_"+i%12);
		}
	}
	
	
	
	public static class DragGridAdapter extends ArrayAdapter<String>{
		 
        public DragGridAdapter(Context context, List<String> objects) {
            super(context, 0, objects);
        }
        public List<String> getList(){
            return list;
        }
 
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view = convertView;
            if(view==null){
                view = LayoutInflater.from(getContext()).inflate(R.layout.drag_grid_item, null);
            }
             
            try {
            	Log.v("item", "------"+getItem(position));
                //根据文件名获取资源文件夹中的图片资源
                Field f= (Field)R.drawable.class.getDeclaredField(getItem(position));
                int i=f.getInt(R.drawable.class);
                ImageView imageview= (ImageView)view.findViewById(R.id.drag_grid_item_image);
                imageview.setImageResource(i);
            } catch (SecurityException e) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            return view;
        }
    }

}

2、DragGridView.java

package com.jay.draggridview;

import com.jay.draggridview.MainActivity.DragGridAdapter;

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.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.Toast;

public class DragGridView extends GridView{

	 //定义基本的成员变量
    private ImageView dragImageView;
    private int dragSrcPosition;
    private int dragPosition;
    //x,y坐标的计算
    private int dragPointX;
    private int dragPointY;
    private int dragOffsetX;
    private int dragOffsetY;
     
    private WindowManager windowManager;
    private WindowManager.LayoutParams windowParams;
     
    private int scaledTouchSlop;
    private int upScrollBounce;
    private int downScrollBounce;
	
	
	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();
	         
	        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_drag);
	        //如果选中拖动图标
	        if(dragger!=null&&dragPointX>dragger.getLeft()&&dragPointX<dragger.getRight()&&dragPointY>dragger.getTop()&&dragPointY<dragger.getBottom()+20){
	 
	            upScrollBounce = Math.min(y-scaledTouchSlop, getHeight()/4);
	            downScrollBounce = Math.max(y+scaledTouchSlop, getHeight()*3/4);
	             
	            itemView.setDrawingCacheEnabled(true);
	            Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache());
	            startDrag(bm, x, y);
	        }
	        return false;
	     }
	     return super.onInterceptTouchEvent(ev);
	}
	
	
	
	@Override
	public boolean onTouchEvent(MotionEvent ev) {
	    if(dragImageView!=null&&dragPosition!=INVALID_POSITION){
	        int action = ev.getAction();
	        switch(action){
	            case MotionEvent.ACTION_UP:
	                int upX = (int)ev.getX();
	                int upY = (int)ev.getY();
	                stopDrag();
	                onDrop(upX,upY);
	                break;
	            case MotionEvent.ACTION_MOVE:
	                int moveX = (int)ev.getX();
	                int moveY = (int)ev.getY();
	                onDrag(moveX,moveY);
	                break;
	            default:break;
	        }
	        return true;
	    }
	    return super.onTouchEvent(ev);
	}
	
	
	
	public void startDrag(Bitmap bm, int x, int y){
	    stopDrag();
	     
	    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.format = PixelFormat.TRANSLUCENT;
	    windowParams.windowAnimations = 0;
	 
	    ImageView imageView = new ImageView(getContext());
	    imageView.setImageBitmap(bm);
	    windowManager = (WindowManager)getContext().getSystemService("window");
	    windowManager.addView(imageView, windowParams);
	    dragImageView = imageView;
	}
	 
	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);
	    }
	 
	    int tempPosition = pointToPosition(x, y);
	    if(tempPosition!=INVALID_POSITION){
	        dragPosition = tempPosition;
	    }
	     
	    //滚动
	    if(y<upScrollBounce||y>downScrollBounce){
	        //使用setSelection来实现滚动
	        setSelection(dragPosition);
	    }        
	}
	
	public void onDrop(int x, int y){
        
        //为了避免滑动到分割线的时候,返回-1的问题
        int tempPosition = pointToPosition(x, y);
        if(tempPosition!=INVALID_POSITION){
            dragPosition = tempPosition;
        }
         
        //超出边界处理
        if(y<getChildAt(0).getTop()){
            //超出上边界
            dragPosition = 0;
        }else if(y>getChildAt(getChildCount()-1).getBottom()||(y>getChildAt(getChildCount()-1).getTop()&&x>getChildAt(getChildCount()-1).getRight())){
            //超出下边界
            dragPosition = getAdapter().getCount()-1;
        }
         
        //数据交换
        if(dragPosition!=dragSrcPosition&&dragPosition>-1&&dragPosition<getAdapter().getCount()){
            DragGridAdapter adapter = (DragGridAdapter)getAdapter();
            String dragItem = adapter.getItem(dragSrcPosition);
            adapter.remove(dragItem);
            adapter.insert(dragItem, dragPosition);
            Toast.makeText(getContext(), adapter.getList().toString(), Toast.LENGTH_SHORT).show();
        }
         
    }
	
	
	/***
	 * 停止拖动,去掉拖动时候的影像
	 */
	public void stopDrag(){
		if(dragImageView != null){
			windowManager.removeView(dragImageView);
			dragImageView = null;
		}
	}
}

3、activity_main.xml

<?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"
    android:background="#ffffff"
    android:padding="10dip"
    >
    <com.jay.draggridview.DragGridView 
        android:id="@+id/drag_grid"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:cacheColorHint="#00000000"
        android:numColumns="3"
        android:stretchMode="columnWidth"
        android:verticalSpacing="5dip"
        android:horizontalSpacing="20dip"
        android:background="#ffffff"/>
</LinearLayout>

4drag_grid_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="5dip"
    android:paddingRight="5dip">
    <ImageView android:id="@+id/drag_grid_item_image"
       android:layout_margin="5dip"
       android:layout_alignParentTop="true"
       android:layout_width="fill_parent"
       android:layout_height="60dip"/>
    <ImageView android:id="@+id/drag_grid_item_drag"
       android:src="@drawable/p32_24_1"
       android:layout_alignParentTop="true"
       android:layout_alignParentRight="true"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>
</RelativeLayout>

源码下载地址:

http://pan.baidu.com/share/link?shareid=465494&uk=1997312776



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值