Android 实现拖放控件

作者: 一个不安分的Android开发 | 来源:发表于2021-07-28 18:25 被阅读0次

    类似微信朋友圈删除图片效果,示例如下:

    拖放控件1.png
    拖放控件2.png

    使用 Android 拖放框架 ,可以让用户使用图形化拖放手势移动数据。

    监听拖放过程

    实现 View.OnDragListener 的拖动事件监听器或其 onDragEvent(DragEvent) 回调方法来接收拖动事件。

    DragEvent 操作类型

    getAction() 值 含义
    ACTION_DRAG_STARTED 当应用调用 startDrag() 并获取拖动阴影后,视图对象的拖动事件监听器会立即收到此事件操作类型。
    ACTION_DRAG_ENTERED 当拖动阴影刚进入视图的边界框时,视图对象的拖动事件监听器会收到此事件操作类型。这是监听器在拖动阴影进入边界框时收到的第一个事件操作类型。如果监听器想继续接收此操作的拖动事件,必须向系统返回布尔值 true
    ACTION_DRAG_LOCATION 当收到 ACTION_DRAG_ENTERED 事件且拖动阴影仍在视图的边界框内时,该视图对象的拖动事件监听器会收到此事件操作类型。
    ACTION_DRAG_EXITED 当收到 ACTION_DRAG_ENTERED 和至少一个 ACTION_DRAG_LOCATION 事件,并且用户已将拖动阴影移至视图的边界框以外时,该视图对象的拖动事件监听器会收到此事件操作类型。
    ACTION_DROP 当用户将拖动阴影释放到视图对象上时,该视图对象的拖动事件监听器会收到此事件操作类型。仅当视图对象的监听器在响应 ACTION_DRAG_STARTED 拖动事件时返回布尔值 true 时,系统才会将该操作类型发送至该监听器。如果用户将拖动阴影释放到未注册监听器的视图上或不属于当前布局的任何视图上,系统都不会发送此操作类型。如果成功处理了放下操作,监听器应返回布尔值 true。否则,它应返回 false
    ACTION_DRAG_ENDED 当系统结束拖动操作时,视图对象的拖动事件监听器会收到此事件操作类型。此操作类型不一定在 ACTION_DROP 事件之后。如果系统已发送 ACTION_DROP,收到 ACTION_DRAG_ENDED 操作类型并不表示放下操作成功。监听器必须调用 getResult() 才能获得响应 ACTION_DROP 时所返回的值。如果未发送 ACTION_DROP 事件,getResult() 将返回 false

    示例代码如下:

    private void initDragListener() {
    
        llDelete.setOnDragListener((v, event) -> {
          final int action = event.getAction();
    
          switch (action) {
            //开始拖动
            case DragEvent.ACTION_DRAG_STARTED:
    
              //离开底部删除按钮
            case DragEvent.ACTION_DRAG_EXITED:
              //重置底部删除按钮文字和颜色
              tvDelete.setText(getString(R.string.delete));
              llDelete.setBackground(
                  ResourcesCompat.getDrawable(getResources(), R.color.delete_msg_color, null));
    
              return true;
    
            //拖动到底部删除按钮中
            case DragEvent.ACTION_DRAG_ENTERED:
              //改变底部删除按钮文字和颜色   
              tvDelete.setText(getString(R.string.delete_hint));
              llDelete
                  .setBackground(ResourcesCompat.getDrawable(getResources(), R.color.delete_hint_color, null));
              return true;
    
            //删除图片
            case DragEvent.ACTION_DROP:
              deleteImage();
              return true;
    
            //拖放结束
            case DragEvent.ACTION_DRAG_ENDED:
              //隐藏底部删除按钮    
              showBottomDelete(false);
              tvDelete.setText(getString(R.string.delete));
              llDelete.setBackground(
                  ResourcesCompat.getDrawable(getResources(), R.color.delete_msg_color, null));
              return true;
    
            default:
              break;
          }
    
          return false;
        });
    
      }
    
      private void deleteImage() {
        imageView.setVisibility(View.GONE);
      }
    

    开始拖动

    根据需要,可以为要移动的数据创建 ClipDataClipData.Item。这个数据通过 DragEvent.getClipData() 方法获取。

    如果不需要也可以直接置空。

    //长按图片触发删除事件    
    imageView.setOnLongClickListener(new OnLongClickListener() {
          @Override
          public boolean onLongClick(View view) {
    
            showBottomDelete(true);
            //创建需要移动的数据,如果没有可以直接置空  
            ClipData.Item item = new Item("");
            ClipData data = new ClipData("", new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN},
                item);
              
            //设置拖动的阴影,可以自定义,这边直接使用ImageView  
            View.DragShadowBuilder myShadow = new DragShadowBuilder(view);
            
            //开始拖动  
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
              view.startDragAndDrop(data, myShadow, null, 0);
            } else {
              view.startDrag(data, myShadow, null, 0);
            }
    
            return false;
          }
        });
    

    相关文章

      网友评论

        本文标题:Android 实现拖放控件

        本文链接:https://www.haomeiwen.com/subject/wtzzmltx.html