关闭

GridView长按拖拽Item效果(android) !!!

标签: androidnullexceptionstringobjectexchange
1728人阅读 评论(1) 收藏 举报
分类:

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

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

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

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


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

  1. package com.pl;  
  2.   
  3. import com.pl.MainActivity.ImageAdapter;  
  4.   
  5. import android.content.Context;  
  6. import android.graphics.Bitmap;  
  7. import android.graphics.PixelFormat;  
  8. import android.util.AttributeSet;  
  9. import android.view.Gravity;  
  10. import android.view.MotionEvent;  
  11. import android.view.View;  
  12. import android.view.ViewGroup;  
  13. import android.view.WindowManager;  
  14. import android.widget.AdapterView;  
  15. import android.widget.GridView;  
  16. import android.widget.ImageView;  
  17.   
  18. public class DragGridView extends GridView  
  19. {  
  20.   
  21.     private int                         dragPosition;   // 开始拖拽的位置  
  22.     private int                         dropPosition;   // 结束拖拽的位置  
  23.     private int                         dragPointX; // 相对于item的x坐标  
  24.     private int                         dragPointY; // 相对于item的y坐标  
  25.     private int                         dragOffsetX;  
  26.     private int                         dragOffsetY;  
  27.     private ImageView                   dragImageView;  // 拖动item的preview  
  28.   
  29.     private WindowManager               windowManager;  
  30.     private WindowManager.LayoutParams  windowParams;  
  31.   
  32.     private int                         itemHeight;  
  33.   
  34.     public DragGridView(Context context, AttributeSet attrs)  
  35.     {  
  36.         super(context, attrs);  
  37.     }  
  38.   
  39.     boolean flag    = false;  
  40.   
  41.     public void setLongFlag(boolean temp)  
  42.     {  
  43.         flag = temp;  
  44.     }  
  45.   
  46.     public boolean setOnItemLongClickListener(final MotionEvent ev)  
  47.     {  
  48.         this.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener()  
  49.         {  
  50.             @Override  
  51.             public boolean onItemLongClick(AdapterView<?> arg0, View arg1,  
  52.                     int arg2, long arg3)  
  53.             {  
  54.                 // onInterceptTouchEvent(ev);  
  55.                 // TODO Auto-generated method stub  
  56.                 L.l("============on Long Click=========");  
  57.                 L.l("============X:" + ev.getX() + " Y:" + ev.getY());  
  58.   
  59.                 int x = (int) ev.getX();  
  60.                 int y = (int) ev.getY();  
  61.                 L.l("============X:" + x + " Y:" + y);  
  62.                 dragPosition = dropPosition = pointToPosition(x, y);  
  63.                 System.out.println(dragPosition);  
  64.                 if (dragPosition == AdapterView.INVALID_POSITION)  
  65.                 {  
  66.   
  67.                 }  
  68.                 ViewGroup itemView = (ViewGroup) getChildAt(dragPosition  
  69.                         - getFirstVisiblePosition());  
  70.                 // 得到当前点在item内部的偏移量 即相对于item左上角的坐标  
  71.                 dragPointX = x - itemView.getLeft();  
  72.                 dragPointY = y - itemView.getTop();  
  73.   
  74.                 dragOffsetX = (int) (ev.getRawX() - x);  
  75.                 dragOffsetY = (int) (ev.getRawY() - y);  
  76.                   
  77.                 itemHeight=itemView.getHeight();  
  78.   
  79.                 L.l("========================y:" + y + " getRawY:"  
  80.                         + ev.getRawY());  
  81.   
  82.                 // 解决问题3  
  83.                 // 每次都销毁一次cache,重新生成一个bitmap  
  84.                 itemView.destroyDrawingCache();  
  85.                 itemView.setDrawingCacheEnabled(true);  
  86.                 Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache());  
  87.                 // 建立item的缩略图  
  88.                 startDrag(bm, x, y);  
  89.                 return false;  
  90.             };  
  91.         });  
  92.         return super.onInterceptTouchEvent(ev);  
  93.     }  
  94.   
  95.     @Override  
  96.     public boolean onInterceptTouchEvent(MotionEvent ev)  
  97.     {  
  98.         if (ev.getAction() == MotionEvent.ACTION_DOWN)  
  99.         {  
  100.             return setOnItemLongClickListener(ev);  
  101.         }  
  102.         return super.onInterceptTouchEvent(ev);  
  103.     }  
  104.   
  105.     private void startDrag(Bitmap bm, int x, int y)  
  106.     {  
  107.         stopDrag();  
  108.   
  109.         windowParams = new WindowManager.LayoutParams();  
  110.         System.out.println("X: " + x + " dragPointX: " + dragPointX  
  111.                 + " dragOffsetX: " + dragOffsetX);  
  112.         windowParams.gravity = Gravity.TOP | Gravity.LEFT;// 这个必须加  
  113.         // 得到preview左上角相对于屏幕的坐标  
  114.         windowParams.x = x - dragPointX + dragOffsetX;  
  115.         windowParams.y = y - dragPointY + dragOffsetY;  
  116.         // L.l("==================windowParams.y==============="+windowParams.y);  
  117.         // 设置宽和高  
  118.         windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;  
  119.         windowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;  
  120.         windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE  
  121.                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE  
  122.                 | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON  
  123.                 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;  
  124.   
  125.         windowParams.format = PixelFormat.TRANSLUCENT;  
  126.         windowParams.windowAnimations = 0;  
  127.   
  128.         ImageView iv = new ImageView(getContext());  
  129.         iv.setImageBitmap(bm);  
  130.         windowManager = (WindowManager) getContext().getSystemService(  
  131.                 Context.WINDOW_SERVICE);// "window"  
  132.         windowManager.addView(iv, windowParams);  
  133.         dragImageView = iv;  
  134.     }  
  135.   
  136.     @Override  
  137.     public boolean onTouchEvent(MotionEvent ev)  
  138.     {  
  139.         if (dragImageView != null  
  140.                 && dragPosition != AdapterView.INVALID_POSITION)  
  141.         {  
  142.             int x = (int) ev.getX();  
  143.             int y = (int) ev.getY();  
  144.             switch (ev.getAction())  
  145.             {  
  146.                 case MotionEvent.ACTION_MOVE:  
  147.                     onDrag(x, y);  
  148.                     break;  
  149.                 case MotionEvent.ACTION_UP:  
  150.                     stopDrag();  
  151.                     onDrop(x, y);  
  152.                     break;  
  153.             }  
  154.         }  
  155.         return super.onTouchEvent(ev);  
  156.     }  
  157.   
  158.     private void onDrag(int x, int y)  
  159.     {  
  160.         if (dragImageView != null)  
  161.         {  
  162.             windowParams.alpha = 0.6f;  
  163.             windowParams.x = x - dragPointX + dragOffsetX;  
  164.             windowParams.y = y - dragPointY + dragOffsetY;  
  165.             // L.l("=================windowParams.y=====000========"+windowParams.y);  
  166.             windowManager.updateViewLayout(dragImageView, windowParams);  
  167.         }  
  168.   
  169.         int tempScrollX = x - dragPointX + dragOffsetX;  
  170.         int tempScrollY = y - dragPointY + dragOffsetY;  
  171.   
  172.         if (tempScrollY +itemHeight> 600)  
  173.         {  
  174.             this.scrollTo(0, tempScrollY);  
  175.         }  
  176.         else  
  177.             if (pointToPosition(x, y) > 2)  
  178.             {  
  179.   
  180.                 this.scrollTo(0, tempScrollY - 300);  
  181.             }  
  182.   
  183.     }  
  184.   
  185.     private void onDrop(int x, int y)  
  186.     {  
  187.         int tempPosition = pointToPosition(x, y);  
  188.         if (tempPosition != AdapterView.INVALID_POSITION)  
  189.         {  
  190.             dropPosition = tempPosition;  
  191.         }  
  192.         if (dropPosition != dragPosition)  
  193.         {  
  194.             System.out.println("dragPosition: " + dragPosition  
  195.                     + " dropPosition: " + dropPosition);  
  196.             ImageAdapter adapter = (ImageAdapter) this.getAdapter();  
  197.             adapter.exchange(dragPosition, dropPosition);  
  198.   
  199.             // 解决问题3  
  200.             /* 
  201.              * ViewGroup itemView1 = (ViewGroup)getChildAt(dragPosition - getFirstVisiblePosition()); ViewGroup 
  202.              * itemView2 = (ViewGroup)getChildAt(dropPosition - getFirstVisiblePosition()); 
  203.              * itemView1.destroyDrawingCache(); itemView2.destroyDrawingCache(); 
  204.              */  
  205.         }  
  206.     }  
  207.   
  208.     private void stopDrag()  
  209.     {  
  210.         if (dragImageView != null)  
  211.         {  
  212.             windowManager.removeView(dragImageView);  
  213.             dragImageView = null;  
  214.         }  
  215.     }  
  216.   
  217. }  

  1. package com.pl;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Context;  
  5. import android.os.Bundle;  
  6. import android.view.LayoutInflater;  
  7. import android.view.View;  
  8. import android.view.ViewGroup;  
  9. import android.widget.AdapterView;  
  10. import android.widget.AdapterView.OnItemClickListener;  
  11. import android.widget.BaseAdapter;  
  12. import android.widget.ImageView;  
  13. import android.widget.TextView;  
  14.   
  15. import java.util.ArrayList;  
  16. import java.util.List;  
  17.   
  18.   
  19. public class MainActivity extends Activity {  
  20.     private DragGridView gv;  
  21.     private List<String> list = new ArrayList<String>();  
  22.     @Override  
  23.     public void onCreate(Bundle savedInstanceState) {  
  24.         super.onCreate(savedInstanceState);  
  25.         setContentView(R.layout.main);  
  26.           
  27.         initData();  
  28.           
  29.         gv = (DragGridView)findViewById(R.id.drag_grid);  
  30.         gv.setAdapter(new ImageAdapter(this));  
  31.         gv.setOnItemClickListener(new OnItemClickListener()  
  32.         {  
  33.   
  34.             @Override  
  35.             public void onItemClick(AdapterView<?> parent, View view,  
  36.                     int position, long id)  
  37.             {  
  38.                 // TODO Auto-generated method stub  
  39.                 L.l("============onItemClick====position:"+position);  
  40.             }  
  41.               
  42.         } );  
  43.           
  44.   
  45.     }  
  46.       
  47.     private void initData(){  
  48.         for(int i=1;i<100;i++){  
  49.             list.add(""+i);  
  50.         }  
  51.     }  
  52.       
  53.     public class ImageAdapter extends BaseAdapter{  
  54.         private Context mContext;  
  55.         private LayoutInflater lif;  
  56.         public ImageAdapter(Context c){  
  57.             mContext = c;  
  58.             lif = LayoutInflater.from(c);  
  59.         }  
  60.           
  61.         public int getCount() {  
  62.             return list.size();  
  63.         }  
  64.   
  65.         public Object getItem(int position) {  
  66.             // TODO Auto-generated method stub  
  67.             return list.get(position);  
  68.         }  
  69.   
  70.         public long getItemId(int position) {  
  71.             // TODO Auto-generated method stub  
  72.             return position;  
  73.         }  
  74.   
  75.         /** 
  76.          * 遇到的问题: 
  77.          * 1、删除错了 会有重复的图片 
  78.          * 这个是由 remove引起的 
  79.          *  删除时 我们先删除了小的position 
  80.          * 比如说 startPosition = 2;endPosition = 3; 
  81.          * 当我先删startPosition时 这时 删除前position为3的项 已经是position为2了  
  82.          * 2、数组越界 异常 
  83.          * 这个是由 add引起的 
  84.          * 比如说 startPosition = 8;endPosition = 7; 
  85.          * 一共gridview有9个元素 也就是说8 已经是最大的了 
  86.          * 当删除完后 你先增加爱 startposition时  就会异常了 
  87.          * 3、preview问题 
  88.          * 当我拖拽互换几次后 机会出现 当前的图片 显示的是另一个图片的preview 
  89.          *  
  90.          * 得调用 destroyDrawingCache 
  91.          * @param startPosition 
  92.          * @param endPosition 
  93.          */  
  94.         public void exchange(int startPosition, int endPosition){  
  95.             //比较一下 使startPosition永远小于endPosition的值 解决问题1 ,2  
  96.             if(startPosition > endPosition){  
  97.                 int temp = endPosition;  
  98.                 endPosition = startPosition;  
  99.                 startPosition = temp;  
  100.             }  
  101.             Object endObject = getItem(endPosition);  
  102.             Object startObject = getItem(startPosition);  
  103.             //list.remove(endPosition);  
  104.             //list.remove(startPosition);  
  105.             System.out.println(startPosition + "========"+endPosition);  
  106.             list.set(startPosition,(String)endObject);  
  107.             list.set(endPosition,(String)startObject);  
  108.             notifyDataSetChanged();  
  109.         }  
  110.           
  111.         public View getView(int position, View convertView, ViewGroup parent) {  
  112.             //ImageView iv;  
  113.             if(convertView==null){  
  114.                 convertView = lif.inflate(R.layout.grid_item, null);  
  115. //                iv = new ImageView(mContext);  
  116. //                try{  
  117. //                Field f = (Field)R.drawable.class.getDeclaredField(list.get(position));  
  118. //                int i = f.getInt(R.drawable.class);  
  119. //                iv.setImageResource(i);  
  120. //                }catch(Exception e){  
  121. //                    e.printStackTrace();  
  122. //                }  
  123.             }  
  124.                   
  125.             try {  
  126.              
  127.                   
  128.                 TextView  textView=(TextView)convertView.findViewById(R.id.textView);  
  129.                 textView.setText(list.get(position));  
  130.                 ImageView  imgView=(ImageView)convertView.findViewById(R.id.image);  
  131.                 imgView.setBackgroundResource(R.drawable.icon);  
  132.                   
  133.             } catch (Exception e) {  
  134.                 e.printStackTrace();  
  135.             }  
  136.             return convertView;  
  137.         }  
  138.           
  139.     }  
  140. }  


三.完整代码如下下载

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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:265799次
    • 积分:3178
    • 等级:
    • 排名:第10778名
    • 原创:23篇
    • 转载:216篇
    • 译文:0篇
    • 评论:19条
    最新评论