zoukankan      html  css  js  c++  java
  • Android drag drop

    最近偶尔知道了锤子的one step,所以在网上看相关的东西,有人说android原生drag drop就能实现,我就去学习一下这个drag drop,下面把学习到的东西总结一下:

    drag drop 是需要两个或者两个以上的View 实现的。就是将一个View从某一个位置拖放到另一个位置,在拖放过程中必须有两个或两个以上的View参与,一个是被拖的View,另一个或多个是接收被拖View的View。这一过程可以将拖拽中携带的数据经行传递。下面一步步咱们来解说:

    ① 那个被拖拽的View,需要做的操作:

      * 对用户操作经行响应:设置长点击事件(OnLongClickListener)或者点击事件(OnClickListener

      * 包装传递的数据(ClipData),如果不需要传递数据,开启时第一个参数为null 即可。

      * 定义拖拽过程中的Shadow(View.DragShadowBuilder),可以使用系统默认的DragShadowBuilder

      * 上述三步完成,第四步 Starts a drag and drop operation

        (public final boolean startDrag (ClipData data, View.DragShadowBuilder shadowBuilder, Object myLocalState, int flags))

     //长按点击事件
    public boolean onLongClick(View v) { // 创建一个ClipData对象 // 这里分为两步,第一步中方法ClipData.newPlainText()可以创建一个纯文本ClipData // 根据ImageView的标签创建一个ClipData.Item对象 ClipData.Item item = new ClipData.Item((CharSequence) v.getTag()); // 使用标签,纯文本和已经创建的item来创建一个ClipData对象 // 这里将在ClipData中创建一个新的ClipDescription对象并设置它的MIME类型为"text/plain" ClipData dragData = new ClipData((CharSequence) v.getTag(), new String[] { ClipDescription.MIMETYPE_TEXT_PLAIN }, item); // 实例化拖拽影子. View.DragShadowBuilder myShadow = new MyDragShadowBuilder(imageView); // 开始拖拽 return v.startDrag(dragData, // 被拖拽的数据 myShadow, // 拖拽的影子 null, // 不需要使用本地数据 0 // 标记(目前用不到,设置为0) ); }

    自定义的DragShadowBuilder:

    private static class MyDragShadowBuilder extends View.DragShadowBuilder {
            // 拖动阴影的图像, 作为一个drawable来定义
            private static Drawable shadow;
            // 构造函数
            public MyDragShadowBuilder(View v) {
                // 通过myDragShadowBuilder存储View参数
                super(v);
                // 创建一个可拖拽的图像,此图像可以通过系统的Canvas来填充
                shadow = new ColorDrawable(Color.LTGRAY);
            }
    
            // 定义一个回调方法,将阴影的维度和触摸点返回给系统
            @Override
            public void onProvideShadowMetrics(Point size, Point touch) {
                // 定义当地的变量
                int width;
                int height;
                // 设置阴影的宽度为视图一半
                width = getView().getWidth() / 2;
                // 设置阴影的高度为视图一半
                height = getView().getHeight() / 2;
                // 拖拽阴影是一个ColorDrawable. 这个集合的维度和系统所提供的Canvas是一样的
                // 因此,拖拽阴影将会被Canvas覆盖
                shadow.setBounds(0, 0, width, height);
                // 设置参数宽度和高度的大小.通过大小参数返回给系统
                size.set(width, height);
                // 设置触摸点的位置为拖拽阴影的中心
                touch.set(width / 2, height / 2);
            }
    
            // 在画布Canvas中定义一个回调函数来绘制拖拽的阴影,该画布是通过方法onProvideShadowMetrics()提供的维度
            // 由系统构造
            @Override
            public void onDrawShadow(Canvas canvas) {
                // 在由系统传递的Canvas上绘制ColorDrawable
                shadow.draw(canvas);
            }
        }
    

    ② 要接受拖拽的View,需要的操作:

      * 设置拖动事件监听器(OnDragListener

      注:这个要接受拖拽的View,可以通过设置拖动事件监听器来监听拖拽。如果它是自定义的View也可以重写View的onDragEvent()方法对拖拽进行监听。

    自定义View实现onDragEvent方法:打印的log很明白告诉你,对应操作的含义:

    public boolean onDragEvent(DragEvent event) {
            boolean result = false; 
             
            switch (event.getAction()) { 
                case DragEvent.ACTION_DRAG_STARTED: { 
                     
                    Log.i("mayingcai", "有View开始被拖动!");
                     
                    /** 
                     * 在拖动开始时,只有返回true,后面的动作(ACTION_DRAG_ENTERED, ACTION_DRAG_LOCATION, ACTION_DROP)才会被执行! 
                     */ 
                    result = true; 
                     
                    break; 
                }  
          
                case DragEvent.ACTION_DRAG_ENTERED: { 
                     
                    Log.i("mayingcai", "被拖动的View进入当前View!"); 
                     
                    break; 
                }  
          
                case DragEvent.ACTION_DRAG_LOCATION: { 
                     
                    Log.i("mayingcai", "被拖动的View进入当前View后,位置发生改变!"); 
                     
                    break; 
                }  
          
                case DragEvent.ACTION_DROP: { 
                     
                    Log.i("mayingcai", "拖动的View被放入当前View!"); 
                     
                    /** 
                     * 在放时交互两个View的背景。 
                     */ 
                    View mDragView = (View) event.getLocalState(); 
                    Drawable mDragViewBackgroud = mDragView.getBackground();
                    mDragView.setBackgroundDrawable(this.getBackground()); 
                    this.setBackgroundDrawable(mDragViewBackgroud); 
                     
                    break; 
                }  
      
                case DragEvent.ACTION_DRAG_ENDED: { 
                     
                    Log.i("mayingcai", "拖动结束!"); 
                     
                    break; 
                }  
          
                case DragEvent.ACTION_DRAG_EXITED: { 
                     
                    Log.i("mayingcai", "拖动退出!"); 
                     
                    break; 
                }  
          
                default: { 
         
                    break; 
                }  
            }  
      
            return result;  
        }
    

     在开始拖动某一个View时屏幕中所有View的DragEvent.ACTION_DRAG_STARTED事件被触发。当拖拽的View进入对应的View时,会触发DragEvent.ACTION_DRAG_ENTERED,DragEvent.ACTION_DRAG_LOCATION等事件。松开鼠标或者放手后(Drop操作),这时会触发绿色View的DragEvent.ACTION_DROP,DragEvent.ACTION_DRAG_ENDED等事件

    注意一下:onLongClick()方法的返回值 和 onDragEvent的返回值

    参考文章:

    http://blog.csdn.net/mayingcai1987/article/details/6221988

    http://blog.csdn.net/zd_1471278687/article/details/20376377

  • 相关阅读:
    java这个404你能解决吗?
    java发邮件,这个坑你能填吗?
    自动评论csdn博客文章实现
    一款效率神器Ditto
    java加载国际化文件的几种姿势
    这个问题你能答对吗?
    mysql大小写敏感与校对规则
    java、golang日志文件转储压缩实现
    一款很好用的markdown编辑器
    beego与curl三件事
  • 原文地址:https://www.cnblogs.com/aimqqroad-13/p/5993651.html
Copyright © 2011-2022 走看看