利用android拖拽框架实现GirdView拖拽

 利用android拖拽框架实现GirdView拖拽很简单,按照帮助文档实现即可。

首先要有影像制造器View.DragShadowBuilder,然后在长按的点击事件里面生成item的影像,最后自定义一个实现了OnDragListener接口的监听器,具体的识别,逻辑操作在监听器里面做。

 

  
  
  
  
  1. public class MyDragShadowBuilder  extends View.DragShadowBuilder  { 
  2.  
  3.        // 拖动阴影图像,定义为一个drawable 
  4.     private static Drawable shadow; 
  5.  
  6.  
  7.     // 定义myDragShadowBuilder的构造方法 
  8.     public MyDragShadowBuilder(View v) { 
  9.  
  10.         // 保存传给myDragShadowBuilder的View参数 
  11.         super(v); 
  12.  
  13.         // 创建一个可拖动的图像,用于填满系统给出的Canvas 
  14.         shadow = new ColorDrawable(Color.LTGRAY); 
  15.     } 
  16.  // 定义回调方法,用于在Canvas上绘制拖动阴影,Canvas由系统根据onProvideShadowMetrics()传入的尺寸参数创 
  17.     @Override 
  18.     public void onDrawShadow(Canvas canvas) { 
  19.          // 在系统传入的Canvas上绘制ColorDrawable 
  20.         super.onDrawShadow(canvas); 
  21.     } 
  22.      // 定义一个回调方法,用于把拖动阴影的大小和触摸点位置返回给系统 
  23.     @Override 
  24.     public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) { 
  25.         // 定义本地变量 
  26.         int width; 
  27.         int height; 
  28.  
  29.         // 把阴影的宽度设为原始View的一半 
  30.         width = getView().getWidth() / 2
  31.  
  32.         // 把阴影的高度设为原始View的一半 
  33.         height = getView().getHeight() / 2
  34.  
  35.         // 拖动阴影是一个ColorDrawable对象。 
  36.         // 下面把它设为与系统给出的Canvas一样大小。这样,拖动阴影将会填满整个Canvas。 
  37.         shadow.setBounds(00, width, height); 
  38.         // 设置长宽值,通过size参数返回给系统。 
  39.         shadowSize.set(width, height); 
  40.         // 把触摸点的位置设为拖动阴影的中心 
  41.         shadowTouchPoint.set(width / 2, height / 2); 
  42.         super.onProvideShadowMetrics(shadowSize, shadowTouchPoint); 
  43.     } 
  44.  

 

  
  
  
  
  1. protected class myDragEventListener implements OnDragListener { 
  2.  
  3.         // 这是系统向侦听器发送拖动事件时将会调用的方法 
  4.  
  5.         @Override 
  6.         public boolean onDrag(View v, DragEvent event) { 
  7.  
  8.             // 定义一个变量,用于保存收到事件的action类型 
  9.             final int action = event.getAction(); 
  10.  
  11.             // 获取自己的图片名称和位置 
  12.             for (int j = 0; j < 7; j++) { 
  13.                 if (v.equals(grid.getChildAt(j))) { 
  14.  
  15.                     Log.d("GirdView的item""这是第" + j + "个item"); 
  16.                     girdViewItemposition = j; 
  17.                     girdViewItemName = list.get(j); 
  18.                 } 
  19.             } 
  20.             // 获取包含拖动数据的item 
  21.             // ClipData.Item item = event.getClipData().getItemAt(0); 
  22.  
  23.             // 从数据项中获取文本数据 
  24.  
  25.             // String dragData_cc = (String) item.getText(); 
  26.  
  27.             Log.d(tag, "Dragged data is " + shadowName); 
  28.  
  29.             // 处理所有需要的事件 
  30.             switch (action) { 
  31.  
  32.             case DragEvent.ACTION_DRAG_STARTED: 
  33.                 // 在应用程序调用 startDrag()并获得一个拖动阴影之后,视图对象的拖动事件监听器就会接收到这个事件类型的事件。 
  34.                 // 确定本View是否接受拖动数据 
  35.                 if (event.getClipDescription().hasMimeType( 
  36.                         ClipDescription.MIMETYPE_TEXT_PLAIN)) { 
  37.                     Log.d(tag, "started:"); 
  38.  
  39.                     return (true); 
  40.  
  41.                 } else { 
  42.  
  43.                     // 返回false。在本次拖放操作中,本View不再会收到拖放事件,除非发出了ACTION_DRAG_ENDED。 
  44.                     return (false); 
  45.  
  46.                 } 
  47.             case DragEvent.ACTION_DRAG_ENTERED: 
  48.                 // 当拖动阴影刚刚进入视图的边界框范围时,视图的拖动事件监听器就会接收到这个action类型的事件。 
  49.                 // 这是当拖动阴影进入视图的边界框范围时监听器所接收到的第一个事件操作类型。如果监听器还行继续为 
  50.                 // 拖动阴影进入视图边界框范围之这个动作接收拖动事件的话,那么必须返回true给系统。 
  51.                 Log.d(tag, "entered:影像进入第" + girdViewItemposition + "个GirdVie"); 
  52.                 Log.d(tag, "GridView图像名称为:" + girdViewItemName); 
  53.                 // 把View的色彩滤镜设置为绿色。返回true,但返回值将被忽略。 
  54.  
  55.                 return (true); 
  56.  
  57.             case DragEvent.ACTION_DRAG_LOCATION: 
  58.                 // 当拖动阴影还在视图的边界框范围中,视图的拖动事件监听器就会在接收到ACTION_DRAG_ENTERED事件 
  59.                 // 之后接收到这个操作类型的事件。 
  60.                 // 忽略事件 
  61.                 return (true); 
  62.  
  63.             case DragEvent.ACTION_DRAG_EXITED: 
  64.                 /** 
  65.                  *  
  66.                  * 当视图的拖动事件监听器接收到ACTION_DRAG_ENTERED这个事件, 
  67.                  * 并且至少接收到一个ACTION_DRAG_LOCATION事件, 
  68.                  * 那么在用户把拖动阴影移除视图的边界框范围之后,该监听器就会在接收到这个操作类型的事件。 
  69.                  *  
  70.                  *  
  71.                  */ 
  72.                 // 影像离开item视图 
  73.                 Log.d(tag, "exited:"); 
  74.  
  75.                 return (true); 
  76.  
  77.             case DragEvent.ACTION_DROP: 
  78.                 /** 
  79.                  *  
  80.                  * 当用户在视图对象上释放拖动阴影时,该视图对象的拖动事件监听器就会接收到这个类型的拖动事件。 这个操作类型只会发送给在回应 
  81.                  * ACTION_DRAG_STARTED类型的拖动事件中返回true的那个视图对象的监听器 
  82.                  * 。如果用户释放拖动阴影的那个视图没有注册监听器 
  83.                  * ,或者用户在当前布局之外的任何对象上释放了拖动阴影,那么这个操作类型就不会被发送。 
  84.                  * 如果释放动作顺利,监听器应该返回true,否则应该返回false。 
  85.                  *  
  86.                  */ 
  87.                 Log.d(tag, "drop:"); 
  88.  
  89.                 // 显示一个包含拖动数据的信息 
  90.                 Toast.makeText(MainActivity.this"Dragged data is " 
  91.                         + shadowName, Toast.LENGTH_LONG); 
  92.  
  93.                 list.remove(girdViewItemposition); 
  94.                 list.add(girdViewItemposition, shadowName); 
  95.                 list.remove(sgadowPosition); 
  96.                 list.add(sgadowPosition, girdViewItemName); 
  97.  
  98.                 adapter.notifyDataSetChanged(); 
  99.                 Log.d("--remove后--", adapter.getList().toString()); 
  100.                 Toast.makeText(MainActivity.this, adapter.getList().toString(), 
  101.                         Toast.LENGTH_SHORT).show(); 
  102.  
  103.                 // 返回true。 DragEvent.getResult()也将返回true. 
  104.                 return (true); 
  105.             case DragEvent.ACTION_DRAG_ENDED: 
  106.                 /** 
  107.                  * 当系统结束拖动动作时,视图对象的拖动事件监听器就会接收到这个类型的拖动事件。 
  108.                  * 这种操作类型不一定是前面有一个ACTION_DROP事件 
  109.                  * 。如果系统发送一个ACTION_DROP,并接收到一个ACTION_DRAG_ENDED操作类型 
  110.                  * ,并不意味着拖动事件的成功。监听器必须调用getResult()方法来获取在回应 
  111.                  * ACTION_DROP事件中返回的结果。如果ACTION_DROP事件没有被发送 
  112.                  * ,那么getResult()就返回false。 
  113.                  */ 
  114.  
  115.                 // 执行getResult(),显示操作的结果。 
  116.                 if (event.getResult()) { 
  117.                     Toast.makeText(MainActivity.this"The drop was handled."
  118.                             Toast.LENGTH_LONG); 
  119.  
  120.                 } else { 
  121.                     Toast.makeText(MainActivity.this"The drop didn't work."
  122.                             Toast.LENGTH_LONG); 
  123.  
  124.                 } 
  125.  
  126.                 // 返回true; 返回值将被忽略 
  127.                 return (true); 
  128.                 // 收到一个未知的action type 
  129.             default
  130.                 Log.e("DragDrop Example"
  131.                         "Unknown action type received by OnDragListener."); 
  132.  
  133.                 break
  134.             } 
  135.             return false
  136.         } 
  137.     } 
  138.  

 

  
  
  
  
  1. grid.setOnItemLongClickListener(new OnItemLongClickListener() { 
  2.  
  3.             @SuppressLint("ParserError"
  4.             @Override 
  5.             public boolean onItemLongClick(AdapterView<?> gridView, View view, 
  6.                     int id, long arg3) { 
  7.  
  8.                 shadowName = list.get(id); 
  9.                 // 为View设置拖动事件侦听器 
  10.                 int count = gridView.getChildCount(); 
  11.                 for (int i = 0; i < count; i++) { 
  12.  
  13.                     gridView.getChildAt(i).setOnDragListener(mDragListen); 
  14.  
  15.                 } 
  16.                 // view.setOnDragListener(mDragListen); 
  17.                 sgadowPosition = id; 
  18.  
  19.                 view.setTag(list.get(id)); 
  20.                 Log.d(tag, "长按的图标名称是:" + list.get(id)); 
  21.                 ClipData.Item item = new ClipData.Item((CharSequence) view 
  22.                         .getTag()); 
  23.                 dragData = new ClipData((CharSequence) view.getTag(), 
  24.                         new String[] { "text/plain" }, item); 
  25.                 // 实例化drag shadow builder. 
  26.                 Log.d(tag, "实例化drag shadow builder"); 
  27.                 DragShadowBuilder myShadow = new MyDragShadowBuilder(view); 
  28.  
  29.                 // 开始拖动 
  30.                 Log.d(tag, "开始拖动"); 
  31.  
  32.                 view.startDrag(dragData, // 要拖动的数据 
  33.                         myShadow, // drag shadow builder 
  34.                         null// 不需要用到本地数据 
  35.                         0 // 标志位(目前未启用,设为0) 
  36.                 ); 
  37.                 return true
  38.             } 
  39.         }); 

 

你可能感兴趣的:(android,GirdView,拖拽框架)