GridView长按拖拽Item效果(android)

DragGridView DragGridView支持按滑动。支持动画效果,支持向下跨屏滑动。不过在跨屏滑动的时候存在bug。有兴趣的同学可以修改一下。 立即下载

一.项目要求要长按后拖拽的效果.

网络上有一份代码,存在两个尚未解决的问题:

1)    点击后就拖拽,并且如果你往下滑的时候,界面会受干扰,因为他用的是Action.Move

2)   当拖拽的View跑到快接近手机屏幕边缘时,GridView没有向下移动.


二.于是经过本人修改,实现了长按后才出现拖拽界面的效果,代码如下:

package com.pl;

import com.pl.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.View;
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;

	private int							itemHeight;

	public DragGridView(Context context, AttributeSet attrs)
	{
		super(context, attrs);
	}

	boolean	flag	= false;

	public void setLongFlag(boolean temp)
	{
		flag = temp;
	}

	public boolean setOnItemLongClickListener(final MotionEvent ev)
	{
		this.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener()
		{
			@Override
			public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
					int arg2, long arg3)
			{
				// onInterceptTouchEvent(ev);
				// TODO Auto-generated method stub
				L.l("============on Long Click=========");
				L.l("============X:" + ev.getX() + " Y:" + ev.getY());

				int x = (int) ev.getX();
				int y = (int) ev.getY();
				L.l("============X:" + x + " Y:" + y);
				dragPosition = dropPosition = pointToPosition(x, y);
				System.out.println(dragPosition);
				if (dragPosition == AdapterView.INVALID_POSITION)
				{

				}
				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);
				
				itemHeight=itemView.getHeight();

				L.l("========================y:" + y + " getRawY:"
						+ ev.getRawY());

				// 解决问题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);
	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev)
	{
		if (ev.getAction() == MotionEvent.ACTION_DOWN)
		{
			return setOnItemLongClickListener(ev);
		}
		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;
		// L.l("==================windowParams.y==============="+windowParams.y);
		// 设置宽和高
		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;
			// L.l("=================windowParams.y=====000========"+windowParams.y);
			windowManager.updateViewLayout(dragImageView, windowParams);
		}

		int tempScrollX = x - dragPointX + dragOffsetX;
		int tempScrollY = y - dragPointY + dragOffsetY;

		if (tempScrollY +itemHeight> 600)
		{
			this.scrollTo(0, tempScrollY);
		}
		else
			if (pointToPosition(x, y) > 2)
			{

				this.scrollTo(0, tempScrollY - 300);
			}

	}

	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.pl;

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.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;


public class MainActivity extends Activity {
    private DragGridView gv;
    private List<String> list = new ArrayList<String>();
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        initData();
        
        gv = (DragGridView)findViewById(R.id.drag_grid);
        gv.setAdapter(new ImageAdapter(this));
        gv.setOnItemClickListener(new OnItemClickListener()
		{

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id)
			{
				// TODO Auto-generated method stub
			    L.l("============onItemClick====position:"+position);
			}
        	
		} );
        

    }
    
    private void initData(){
        for(int i=1;i<100;i++){
            list.add(""+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 {
           
                
                TextView  textView=(TextView)convertView.findViewById(R.id.textView);
                textView.setText(list.get(position));
                ImageView  imgView=(ImageView)convertView.findViewById(R.id.image);
                imgView.setBackgroundResource(R.drawable.icon);
                
            } catch (Exception e) {
                e.printStackTrace();
            }
            return convertView;
        }
        
    }
}


三.完整代码如下下载

http://download.csdn.net/detail/synwith/3693769


GridView拖拽Item及自动滚屏效果 感谢原创,感谢分享. GridView,Item后出现漂浮可拖拽Item,并且在此Item移动到边缘时gridView会自动滚屏. 立即下载

相关推荐

GridView(按拖动)

GridView实现Item可拖动,并设置可以移动区域和不可移动区域,值得学习.

Android自定义View实现可以拖拽GridView

主要为大家详细介绍了Android自定义View实现可以拖拽GridView,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

DragGridView:一个android可拖动的gridview,有两种拖动方式,有漂移、回弹、移位动画

拖动网格视图 一个可拖动的网格视图,有两种拖动方式。 并且您可以在拖动时向上或向下 srcoll。 它提供漂移、交换和移位以及回弹动画。 您应该为敏捷适配器实现不断变化的数据。

Android拖拽DragGridView

今天收到一个需求:需要对相册有一个选中,排序,删除等等功能。因为项目的相册是很早以前写的,没有用RecycleView,而是用的最原始的GridView,所以直接重写GridView,也不用修改adpter那些。 1.先上个效果图 2.首先重写Gridview public class DragGridView extends GridView { //拖拽响应的时间 默认为...

XJXMFYM的博客 1万+

【亲测免费】 推荐项目:DragGridView - 一款可拖动排序的Android Grid视图组件

推荐项目:DragGridView - 一款可拖动排序的Android Grid视图组件 在Android应用开发中,我们经常需要实现列表或网格视图中的元素可拖动排序的功能,为此,开发者Guolei1130创建了一个名为DragGridView的开源项目。该项目不仅简化了这一复杂过程,而且提供了出色的用户体验和性能优化。 项目简介 是一个自定义的Android ViewGroup,它扩展了经典的G...

gitblog_00063的博客 513

DragGridView(可拖动GridView实现,含item移动动画)

DragGridView(可拖动GridView实现)蝎子莱莱 xiezilailai

ScorpionLai的博客 4078

Android表格拖拽排序,Android 拖拽排序控件 DragGridView

Android 拖拽排序控件 DragGridViewAndroid 开发中,我们经常会遇到条目拖拽排序的需求,特别是在新闻类应用中就更普遍了.其实,我们在网上可以搜到许多关于拖拽排序的自定义控件,今天,为大家介绍的是一个拖拽排序库 DragGridView ,库中包含自定义控件 DragGridView 以及它的一个封装对话框 DragSortDialog.下面,我们就一起了解一下库的功能及使用...

weixin_33846508的博客 887

Android拖拽GridView效果实现 按可拖拽item实时交换

Android拖拽GridView效果实现 按可拖拽item实时交换

qq_44906554的博客 313

android 拖拽gridview,Android拖拽GridView效果实现, 按可拖拽item实时交换

具体的原理描述,可以去看夏神的这个博文效果图: 这里,采用了gridview的onLongItemClickListener,来拿到按的view,用于拖动解决了,原来实现中可能遇到的item消失问题主要代码:package com.stone.draggridview.my;import android.app.Activity;import android.content.Context;im...

weixin_30895873的博客 838

Android拖拽GridView效果实现, 按可拖拽item实时交换

Android拖拽GridView效果实现, 按可拖拽item实时交换

zhangwang9li的专栏 763

Android拖拽GridView效果实现, 按可拖拽item实时交换

Android开发中,我们常常用到ListView和GridView,而有的时候系统的ListView,GridView并不能满足我们的需求,所以我们需要自己定义一个ListView或者GridView,我的上一篇文章中就是自定义的一个左右滑动删除item的例子,大家有兴趣的可以去看看 Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果,今天这篇文章就给大家来自定义GridView的控件,GridView主要是来显示网格的控件,在Android的开发中使用很普通,相对于

Mobile Internet developer 10万+

Android拖拽GridView效果实现, 按可拖拽item实时交换位置

Android开发中,我们常常用到ListView和GridView,而有的时候系统的ListView,GridView并不能满足我们的需求,所以我们需要自己定义一个ListView或者GridView,我的上一篇文章中就是自定义的一个左右滑动删除item的例子,大家有兴趣的可以去看看 Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果,今天这篇文章就给大家来

mrleeapple的专栏 3211
上一篇: Console输出UTF-8字符集
下一篇: 3D旋转动画(延Y轴旋转)
mokey87654
博客等级 码龄16年 42粉丝 42原创
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值