Android3.0提供了drag/drop框架,利用此框架可以实现使用拖放手势将一个view拖放到当前布局中的另外一个view中。

实现拖放的步骤

首先,我们先了解一下拖放过程,从官方文档可以知道,整个拖放过程共分为4个步骤,具体如下:

1、  Started:启动拖放,主要是调用被拖放View的startDrag方法。此方法原型为:

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

启动后,系统生成拖放阴影并发送action为ACTION_DRAG_STARTED的拖放事件到当前布局中已经设置了拖放监听的View。

2、  Continuing:保持拖动状态。在此过程中系统可能会发送一个或多个拖动事件给设置了拖放监听器的View,比如ACTION_DRAG_ENTERED、ACTION_DRAG_LOCATION等。

3、  Dropped:用户在目标区域内释放拖动阴影,系统会向设置了拖放监听器的View发送action为ACTION_DROP的事件。

4、  Ended:用户释放了拖动阴影,系统会向设置了拖放监听器的View发送action为ACTION_DRAG_ENDED事件,完成拖放。

拖放过程中关键的接口和类

其次,我们要了解清楚拖放过程中的几个关键的接口和类,主要有OnDragListener、DragEvent、DragShadowBuilder、ClipData、ClipDescription等。

1、OnDragListener:接口,拖放事件监听器。当发生Drag时,回调此接口中的方法。接口中只含有一个方法onDrag,方法原型为:

boolean onDrag(View v, DragEvent event)
//参数v:设置了监听器的View
//参数event:拖放事件的参数,封装了拖放相关的数据
//返回值:true-事件已处理;false事件未处理。

2、DragEvent:拖放事件对象,根据action的不同,包含不同的事件数据。

3、DragShadowBuilder:拖放阴影构造者对象,用于构造拖放阴影。

4、ClipData、ClipDescription:用于拖放的移动数据。

code

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/topContainer"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><ImageViewandroid:id="@+id/img"android:layout_width="wrap_content"android:layout_height="wrap_content"android:contentDescription="@null"android:src="@drawable/ic_launcher" /><LinearLayoutandroid:id="@+id/container"android:layout_width="match_parent"android:layout_height="100dp"android:layout_alignParentBottom="true"android:orientation="vertical"android:background="#cccccc" ><TextViewandroid:id="@+id/title"android:layout_width="fill_parent"android:layout_height="wrap_content"android:textColor="#ff0000"android:textSize="18sp" /></LinearLayout></RelativeLayout>

为ImageView绑定长点击事件

imageView.setOnLongClickListener(new OnLongClickListener() {@Overridepublic boolean onLongClick(View v) {//创建移动数据ClipData.Item item = new ClipData.Item((String) v.getTag());ClipData data = new ClipData(IMAGEVIEW_TAG,new String[] { ClipDescription.MIMETYPE_TEXT_PLAIN },item);//调用startDrag方法,第二个参数为创建拖放阴影v.startDrag(data, new View.DragShadowBuilder(v), null, 0);return true;}});

为目标View绑定拖拽监听:

container.setOnDragListener(new OnDragListener() {@Overridepublic boolean onDrag(View v, DragEvent event) {final int action = event.getAction();switch (action) {case DragEvent.ACTION_DRAG_STARTED://拖拽开始事件if (event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {return true;}return false;case DragEvent.ACTION_DRAG_ENTERED://被拖放View进入目标View
                    container.setBackgroundColor(Color.YELLOW);return true;case DragEvent.ACTION_DRAG_LOCATION:return true;case DragEvent.ACTION_DRAG_EXITED://被拖放View离开目标View
                    container.setBackgroundColor(Color.BLUE);title.setText("");return true;case DragEvent.ACTION_DROP://释放拖放阴影,并获取移动数据ClipData.Item item = event.getClipData().getItemAt(0);String dragData = item.getText().toString();title.setText(dragData+event.getY()+":"+event.getX());return true;case DragEvent.ACTION_DRAG_ENDED://拖放事件完成return true;default:break;}return false;}});

imageView的位置

topContainer.setOnDragListener(new OnDragListener() {@Overridepublic boolean onDrag(View v, DragEvent event) {final int action = event.getAction();switch (action) {case DragEvent.ACTION_DRAG_STARTED:return true;case DragEvent.ACTION_DRAG_ENTERED:return true;case DragEvent.ACTION_DRAG_LOCATION:return true;case DragEvent.ACTION_DRAG_EXITED:return true;case DragEvent.ACTION_DROP:imageView.setX(event.getX()-imageView.getWidth()/2);imageView.setY(event.getY()-imageView.getHeight()/2);return true;case DragEvent.ACTION_DRAG_ENDED:return true;default:break;}return false;}});

效果

我是天王盖地虎的分割线

转载:http://www.cnblogs.com/jerehedu/p/4427588.html

Android -- DragDrop相关推荐

  1. Android 高级工程师面试(二)

    五.Android中的动画 1.Android中的动画有哪几类,它们的特点和区别是什么 Android 中动画分为两种,一种是Tween 动画.还有一种是 Frame 动画. Tween动画,这种实现 ...

  2. Android 高级面试

    一. Android 性能优化 1. 如何对 Android 应用进行性能分析 2. 什么情况下会导致内存泄露 3. 如何避免 OOM 异常 4. Android 中如何捕获未捕获的异常 5. ANR ...

  3. Android面试题【高级工程师版】

    Android 高级(★★★) 一. Android 性能优化(11.9 更新) 1. 如何对 Android 应用进行性能分析 2. 什么情况下会导致内存泄露 3. 如何避免 OOM 异常 4. A ...

  4. android All

    Activity Activity的概念 一个Activity通常对应一个能与用户交互的UI(用户界面) Activity分类 FragmentActivity ListActivity TabAct ...

  5. android 拖动控件删除,Android学习------拖动删除(仿微信朋友圈拖动删除)

    1 示例 发朋友圈的时候,长按图片可以调整顺序,还可以拖动到底部删除. 2 官方示例: https://developer.android.google.cn/guide/topics/ui/drag ...

  6. Unity5.6+ 导出Android 应用程序apk的环境配置及导出过程

    首先下载并安装安卓SDK和java的JDK 安卓sdk下载: http://www.android-studio.org/ 也可以在这下载: 链接:http://pan.baidu.com/s/1bp ...

  7. Android 的NDK的Makefile编写

    Android.mk 是google根据Linux GNU Makefile精简编译脚本.具体来说:这就是GNU Makefile的一小部分. 举一个简单例子: LOCAL_PATH := $(cal ...

  8. Android Animation (安卓动画)概念简介

    Android Animation Android 四种动画分别为逐帧动画和补间动画.属性动画.过渡动画: Frame Animation (逐帧动画) 实现方式:xml 和 Java代码 图片跳转的 ...

  9. 基于Android和SpringBoot的购物App

    (Shopping)购物应用商城 本软件使用Android和SpringBoot.JavaWeb技术实现:并结合百度LBS平台的SDK.支付宝App支付客户端SDK.MobTech的ShareSDK: ...

最新文章

  1. Windows Server 2008 R2之三十二:证书注册WEB服务(一)
  2. python template open_python and Template.
  3. 救命,Linux正在吃掉我的内存!
  4. java中有界队列的饱和策略(reject policy)
  5. spring注解式参数校验
  6. rest_framework09:自动生成接口文档(简略)
  7. Java 实例 - 队列(Queue)用法
  8. RHQ指标的WildFly子系统
  9. Dubbo项目基本业务基础构建
  10. html下拉框设置默认值_html 里select 下拉列表中设置默认值怎么写
  11. Getphonenumber获得电话号码的例子
  12. Visual Studio Code compile error - launch.json must be configured...
  13. 无法加载 MySQL ODBC 5.3 Unicode Driver ODBC 驱动程序的安装例程,因为存在错误代码126.
  14. Python编程案例:中文金额转换并计算
  15. 必看!!!一级建造师各科老师推荐!!!
  16. Mac苹果电脑开不了机怎么办,该怎么修复
  17. 快狗打车CTO沈剑:如何利用计划管理提升团队效率和产能
  18. SpringBoot整合Logback日志框架+Slf4j注解使用
  19. python空气质量分析与预测_AQI(空气质量指数)分析与预测(一)
  20. 佳博便携式条码打印机怎么使用_佳博打印机如何设置热敏打印

热门文章

  1. 实用 —— PowerCLI (一)
  2. java的throw_浅谈Java的throw与throws
  3. 论文工具 | 翻译神器
  4. sqlite to mysql_SqliteToMysql
  5. K8s普通用户配置权限解决User “system:anonymous“ cannot list nodes at the cluster scope
  6. java消费者中url找不到,java – URL可以使用浏览器访问,但是仍然是具有URLConnection的FileNotFoundException...
  7. 登录方式1:MySQL自带客户端
  8. ReentrantLock重入锁
  9. 获取Class类对象的三种方式
  10. 方法练习1_比较两个数字是否相同