`

2011.06.21——— android GridView的拖拽

阅读更多
2011.06.21——— 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;
        }
    }
    
    
    

}



MainActivity:

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;
        }
        
    }
}



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"
    >
	<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>



grid_item.xml


<?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>



具体说明 请看代码 里面有详细说明




分享到:
评论
6 楼 zhu071011 2012-12-10  
额,原来定义在mainactivity里面,不好意思。。。
5 楼 zhu071011 2012-12-10  
楼主请问你的ImageAdapter是不是继承自Baedapter?由于您没有把ImageAdapter的源码贴出来,我自己创建了一个,发现并没有exchange这个函数。
4 楼 lipeng88213 2011-09-05  
wuwu20048 写道
图像的交换 好像有问题的。照你这样做 ,更新数据的时候,怎么就是倒叙了一下。图标最后到了最前面

没看明白。。。能稍微详细点
3 楼 wuwu20048 2011-09-05  
图像的交换 好像有问题的。照你这样做 ,更新数据的时候,怎么就是倒叙了一下。图标最后到了最前面
2 楼 lipeng88213 2011-09-02  
wuwu20048 写道
源代码在哪呢?

晕啊。。。代码不是全都贴出来了。。。
1 楼 wuwu20048 2011-09-02  
源代码在哪呢?

相关推荐

    Android源码——GridView拖拽实例源码_new_07.7z

    这个“Android源码——GridView拖拽实例源码_new_07.7z”压缩包包含了实现GridView拖拽功能的示例代码,对于学习如何增强用户交互体验非常有帮助。 GridView的基础知识: 1. **定义**:GridView继承自AbsListView,...

    安卓Android源码——gridview分页效果.zip

    "安卓Android源码——gridview分页效果.zip"这个压缩包可能包含了一个实现GridView分页效果的示例项目。HorizontalGridView是GridView的一个扩展,它使得数据可以横向滚动,提供了更丰富的界面展示方式。 首先,...

    Android源码——GridView拖拽实例源码_new_07.zip

    这个"Android源码——GridView拖拽实例源码_new_07.zip"文件提供了关于如何实现GridView元素拖拽功能的示例代码。这个功能在很多场景下都非常实用,比如在移动应用中调整图片顺序或者在文件管理器中重新排列文件。 ...

    安卓Android源码——GridView拖拽实例源码.zip

    本压缩包提供的“安卓Android源码——GridView拖拽实例源码”是一个实战案例,展示了如何实现GridView中的元素拖拽功能,这对于提升用户体验和增强应用交互性具有重要意义。 首先,我们需要理解GridView的基本用法...

    安卓Andriod源码——gridview分页效果.zip

    "安卓Andriod源码——gridview分页效果.zip"这个压缩包的学习可以帮助开发者理解和实现Android中的GridView分页效果,同时也能掌握HorizontalGridView的使用,提升Android应用的交互体验。实际开发时,应根据项目...

    android Gridview分页实现

    在Android开发中,GridView是一种常用的布局控件,它允许我们以网格的形式展示数据。当我们处理大量数据时,分页加载可以提高应用性能,减少内存消耗,并提供更好的用户体验。本篇文章将详细讲解如何在Android中利用...

    安卓Android源码——gridview分页效果.rar

    这个"安卓Android源码——gridview分页效果.rar"文件很可能是包含了一个实现GridView分页效果的示例项目。分页在大数据量展示时尤为重要,因为它提高了用户体验,避免一次性加载大量数据导致应用性能下降或内存溢出...

    Android中文翻译组——Android中文API——android.widget合集(中)

    `Android中文翻译组——Android中文API——android.widget合集(中).chm`文件很可能是这个主题的中文参考手册,包含了这些控件的详细解释、使用示例和API文档,对于初学者来说是一份宝贵的资源。建议读者仔细阅读并...

    Android GridView拖拽实例源码.zip

    这个“Android GridView拖拽实例源码”项目提供了一个具体的实现,让用户可以拖动GridView中的元素,增强用户体验。下面我们将详细探讨GridView以及如何实现拖放功能。 首先,理解`GridView`。`GridView`是`...

    ——将GridView导出为PDF 通过itextsharp

    2. **GridView控件**:GridView是ASP.NET Web Forms中的一种数据绑定控件,常用于展示表格数据。它可以从数据库或其他数据源动态加载数据,并允许用户进行排序、分页和编辑。 3. **PDF文件格式**:PDF(Portable ...

    Android GridView使用例子

    在Android开发中,GridView是一个非常常用的布局控件,它允许我们以网格的形式展示数据,通常用于创建类似照片墙、应用快捷方式或者菜单等界面。在这个"Android GridView使用例子"中,我们将深入探讨如何有效地利用...

    AndroidGridView点击每一个图片进入个人页面渐变特效.zip

    在Android开发中,GridView是一种常用的布局控件,它允许我们以网格的形式展示数据。这个"AndroidGridView点击每一个图片进入个人页面渐变特效.zip"压缩包包含的资源可能是一个示例项目,展示了如何在GridView中实现...

    android学习——GridView

    在Android开发中,GridView是一种非常常用的布局控件,它允许我们以网格的形式展示数据,通常用于创建像照片墙、应用列表等多列显示的内容。在本教程中,我们将深入探讨如何在Android应用中使用GridView。 首先,...

    Android GridView拖拽实例源码.rar

    这个"Android GridView拖拽实例源码"是一个实用的资源,它提供了实现GridView元素拖放功能的代码示例,这对于提升用户交互体验和优化界面操作具有重要意义。 首先,我们要理解GridView的基本工作原理。GridView继承...

    AndroidGridView拖拽实例源码.zip

    在Android GridView的拖拽操作中,主要涉及以下几个关键知识点: 1. **GridView的基本使用**:首先,我们需要了解GridView的基本用法,包括在XML布局文件中声明GridView,设置其属性如列数(android:numColumns)、...

Global site tag (gtag.js) - Google Analytics