Android为View添加拖放效果的方法实例

作者:QiShare 时间:2023-06-25 18:53:45 

1.引言

在开发中,拖放是一种比较常见的手势操作,使用它能够让应用的交互更加地便捷和友好,本文将简要介绍如何为Android中的View添加拖放效果。

2.主要方法和类介绍

2.1 startDragAndDrop()和startDrag()

要实现View的拖放,需要调用View的startDragAndDrop()或startDrag()方法,其中startDragAndDrop()方法要求API版本为24或以上,调用方法后,View便可以拖动了,此方法需要传递的参数如下:

//data:拖放操作要传递的数据
//shadowBuilder:拖放阴影
//myLocalState:一个包含与拖放操作有关的数据的对象
//flags:控制拖放操作的标志位
public final boolean startDragAndDrop(ClipData data, DragShadowBuilder shadowBuilder,Object myLocalState, int flags)

2.2 setOnDragListener()

接收拖放事件的View我们暂且称之为目标View,目标View调用setOnDragListener(),并实现其中的方法onDrag()后可以接收拖放事件的回调。

2.3 View.DragShadowBuilder

在拖放操作进行的时候,需要显示正在拖动的图片,View.DragShadowBuilder类提供了可以传入View的构造方法,这个View是被拖放的View,我们将通过DragShadowBuilder创建的拖动图片称为拖动阴影,这个将作为参数传入startDragAndDrop()或startDrag()方法中,如若有需要的话,还可以继承View.DragShadowBuilder类去实现自定义的效果。

2.4 DragEvent

此类主要定义了拖放事件的类型,通过event.getAction()可以获取不同的事件类型,主要有以下几种:

//DragEvent.ACTION_DRAG_STARTED:表示拖动已经开始
//DragEvent.ACTION_DRAG_ENTERED:表示拖动阴影已经进入目标View
//DragEvent.ACTION_DRAG_LOCATION:拖动阴影在目标View边界内移动时会多次响应此事件
//DragEvent.ACTION_DRAG_EXITED:表示拖动阴影离开了目标View的边界
//DragEvent.ACTION_DROP:表示拖动阴影被释放
//DragEvent.ACTION_DRAG_ENDED:表示拖放操作即将结束,在此处需要通过调用event.getResult()的返回值来判断拖放操作是否成功

3. 演示将一张图片拖放到方框内

现在演示将一张图片拖放到方框内,来说明拖放操作的大致流程,其中方框是一个LinearLayout,为它设置了一个方框背景。

3.1 简易布局

布局如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity">

<ImageView
       android:id="@+id/iv_drag"
       android:layout_width="100dp"
       android:layout_height="100dp"
       android:layout_centerHorizontal="true"
       android:src="@mipmap/ic_launcher" />

<LinearLayout
       android:id="@+id/ll_accept"
       android:layout_width="300dp"
       android:layout_height="300dp"
       android:layout_alignParentBottom="true"
       android:layout_centerHorizontal="true"
       android:layout_marginBottom="50dp"
       android:background="@drawable/black_bac"
       android:orientation="vertical">
   </LinearLayout>
</RelativeLayout>

3.2 操作被拖放的图片

实现长按拖动图片的效果,首先调用setOnLongClickListener()设置长按事件回调,之后构建ClipData和拖动阴影,然后调用startDragAndDrop()或startDrag()方法实现拖动,代码如下:

iv_drag.setOnLongClickListener(new View.OnLongClickListener() {
   @Override
   public boolean onLongClick(View v) {
       CharSequence charSequence = (CharSequence) iv_drag.getTag();
       ClipData.Item item = new ClipData.Item(charSequence);
       ClipData clipData = new ClipData(charSequence, new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN}, item);
       View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(iv_drag);
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
           iv_drag.startDragAndDrop(clipData, shadowBuilder, null, 0);
       } else {
           iv_drag.startDrag(clipData, shadowBuilder, null, 0);
       }
       return true;
   }
});

3.3 方框接收图片

目标View要接收图片需要先调用setOnDragListener()来接受拖放事件的回调,使用event.getAction()来获取不同的拖放事件类型,然后根据事件类型执行相应的操作,示例如下:

ll_accept.setOnDragListener(new View.OnDragListener() {
   @Override
   public boolean onDrag(View v, DragEvent event) {
       switch (event.getAction()) {
           case DragEvent.ACTION_DRAG_STARTED:
               iv_drag.setVisibility(View.GONE);
               if (event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
                   return true;
               }
               return false;

case DragEvent.ACTION_DRAG_ENTERED:
               isChangePos = true;
               ll_accept.setBackgroundResource(R.drawable.green_bac);
               return true;

case DragEvent.ACTION_DRAG_LOCATION:
               x = event.getX();
               y = event.getY();
               return true;

case DragEvent.ACTION_DRAG_EXITED:
               isChangePos = false;
               ll_accept.setBackgroundResource(R.drawable.black_bac);
               return true;

case DragEvent.ACTION_DROP:

return true;

case DragEvent.ACTION_DRAG_ENDED:
               ll_accept.setBackgroundResource(R.drawable.black_bac);
               if (isChangePos && event.getResult()) {
                   int left = ll_accept.getLeft();
                   int top = ll_accept.getTop();
                   x = x + left - (iv_drag.getWidth() / 2);
                   y = y + top - (iv_drag.getHeight() / 2);
                   iv_drag.setX(x);
                   iv_drag.setY(y);
               }
               iv_drag.setVisibility(View.VISIBLE);
               return true;
       }
       return false;
   }
});

4.总结

在开发的过程中,我们会使用各种各样的View,实现拖放效果,主要包括拖动阴影构建、拖放方法调用以及对拖放事件的处理,在合适的场景下为View添加上拖放效果能让应用交互更加方便和友好。

来源:https://juejin.cn/post/7062961027578757156

标签:android,自定义view,拖放
0
投稿

猜你喜欢

  • 详解Java的Hibernate框架中的List映射表与Bag映射

    2021-09-16 05:35:05
  • Android仿Iphone屏幕底部弹出半透明PopupWindow效果

    2023-08-17 06:14:43
  • Java OkHttp框架源码深入解析

    2023-11-29 03:22:50
  • Android自定义带进度条WebView仿微信加载过程

    2022-05-08 04:52:46
  • Springboot项目全局异常统一处理案例代码

    2021-08-26 10:51:19
  • C#控制台程序使用Log4net日志组件详解

    2023-02-15 19:44:26
  • C#实现DVD借出归还管理系统

    2021-07-02 06:55:38
  • JavaSwing FlowLayout 流式布局的实现

    2023-10-02 03:59:41
  • Java使用BIO和NIO进行文件操作对比代码示例

    2023-04-18 16:14:21
  • Android Handler消息机制分析

    2023-10-01 13:22:26
  • Java+TestNG接口自动化入门详解

    2023-11-05 04:37:58
  • Jquery+Ajax+Json+存储过程实现高效分页

    2022-04-25 02:22:30
  • 如何安装java的运行环境IDEA

    2022-09-20 10:42:38
  • Android实现文件解压带进度条功能

    2023-02-26 19:01:05
  • Java中Equals使用方法汇总

    2022-09-14 23:08:28
  • C#多线程之Thread类详解

    2023-07-23 05:34:46
  • Android中Button实现点击换图案及颜色

    2022-06-28 00:42:10
  • Android切换至SurfaceView时闪屏(黑屏闪一下)以及黑屏移动问题的解决方法

    2023-07-21 10:51:45
  • SpringBoot如何集成PageHelper分页功能

    2022-10-22 03:18:34
  • Java使用Math.random()结合蒙特卡洛方法计算pi值示例

    2023-05-10 10:43:13
  • asp之家 软件编程 m.aspxhome.com