zoukankan      html  css  js  c++  java
  • 【优才原创】Android的拖放机制

                                                            优才网

    【优才原创】Android的拖放机制

    2016-04-18 优才学院 优才网





    一、拖放机制概述

    ² 拖放操作是手指触摸屏幕上的某一对象。然后拖动该对象。最后在屏幕的某个位置释放该对象并运行某种操作。如删除、卸载、启动、复制数据等。

    ² 同意以图形化的手势操作完毕某项任务。

    ² 拖放操作的优势:直观、易用、简化操作步骤。

    ² SDK3.0提供了支持拖放操作的编程机制,简称拖放机制,拖放机制是为数据移动设计的,但可以用于其他的UI操作。如Android系统自带的将托盘内图标代表的应用程序以拖放的方式卸载。

    ² 拖放机制比自编程实现拖放操作更方便,长处包含:

    1、提供了对全部View支持拖放操作的API,无需自己定义View

    2、系统自己主动推断手指的位置。

    3、由系统自己主动绘制影子图形。

    4、系统提供了拖放对象与目标对象之间传递数据的机制。简化了数据传递的编程。

    5、提供了很多其它的拖放事件,如按下、抬起、释放、进入目标区域、仍在目标区域、离开目标区域、结束拖放等六个事件。而且这些事件由系统捕捉、发送,开发人员仅仅需编写处理这些事件的代码。

    ² 拖放机制包含:

    1、响应拖放操作事件的接口。

    2、存放拖放操作相关信息的类;

    3、启动拖放操作的方法;

    4、绘制拖放过程中影子图形的类。

    5、传递数据的类。

    (二)拖放编程步骤

    步骤1、设置被拖放对象的点击或长按或触摸的事件响应代码,在该响应代码中完毕下面操作:

    1)设置传送给目标对象的数据;

    2)设置拖放过程中绘制影子图形的对象;

    3)启动拖放操作。

    步骤2、编写被拖放对象和拖放目标对象的响应拖放事件的代码。

    (三)相关类-ClipData

    1、概述

    ClipData类用于操作剪贴板中的数据,该类支持进程之间传递数据。

    在拖放编程中,该类负责被拖动对象与拖动对象之间的数据传递,该类支持传递Uri、Html文本、纯文本等多种类型的数据。

    2、经常用法

    public static ClipData newPlainText (CharSequence label, CharSequence text)

    作用

    创建一个新的ClipData对象,该对象包括MIMETYPE_TEXT_PLAIN类型的数据

    參数

    label:代表剪贴板中text数据的键。

    text:剪贴板中的数据。

    public ClipData.Item getItemAt (int index)

    作用

    返回剪贴板中的数据。

    參数

    index:数据的索引值。index的值范围[0,getItemIndex-1]

    说明

    若剪贴板中存放的是字符串数据,则由下面代码取出该字符串数据:

    new ClipData().getItemAt(0).getText().toString();

    当中索引值0表示取出的是剪贴板中第一个

    public ClipData.Item getItemAt (int index)

    作用

    返回剪贴板中的数据。

    (四)相关类-DragShadowBuilder

    1、概述

    在拖拽和放下操作期间,系统会显示一张用户拖动的图片。

    对于要移动的数据,这张图片就代表了被拖动的数据。

    对于操作,这张图片就代表了拖动操作的某些外观。

    这张图片被叫做影子图形。由DragShadowBuilder对象来创建。

    DragShadowBuilder类是View类的内部类。

    2、构造方法

    public View.DragShadowBuilder (View view)

    作用

    封装了拖拽中各种事件和控件的位置等信息

    參数

    创建用于绘制影子图形的对象,该对象的基类是View,默认情况下。该影子图形与被拖动图形尺寸同样,影子图形的中心点是View对象的中心点坐标。

    參数

    view:被拖拽的View对象。

    3、与拖拽相关的方法

    public final boolean startDrag (ClipData data,

    View.DragShadowBuilder shadowBuilder, Object myLocalState, int flags)

    作用

    開始拖拽指定的View对象传递给系统。

    參数

    创建用于绘制影子图形的对象,该对象的基类是View,默认情况下,该影子图形与被拖动图形尺寸同样,影子图形的中心点是View对象的中心点坐标。

    參数

    參数-data:存放数据的剪贴板对象。

    shadowBuilder:操作影子图片的对象。

    myLocalState:被拖动对象与目标对象之间传递数据的轻量级结构的对象。

    參数

    flags:用于控制拖拽操作的类型。当前未定该标志值尚没有定义。设置0就可以。

     

    (五)相关接口-OnDragListener

    1、概述

    OnDragListener接口用于响应拖拽的相关事件。

    2、接口中声明的方法

    public boolean onDrag(View view, DragEvent event)

    作用

    封装了拖拽中各种事件和控件的位置等信息

    參数

    view:当前操作的对象,包含被拖拽对象和拖放的目标对象。

    返回值

    false将不会接收兴许的拖动事件

    true将接收兴许的拖动事件。

     

    (六)相关类-DragEvent

    1、概述

    系统用DragEvent对象存储拖放事件的相关信息。

    DragEvent对象包括了一个操作类型,用于告诉监听器在拖放过程中发生的事件。该对象还依据操作类型,包括了其他的数据。

    2、拖放事件常量

     

    常量

    作用

    ACTION_DRAG_STARTED

    调用startDrag()方法。而且获得了拖拽影子后。View对象的拖拽事件监听器才接收这样的事件操作

    ACTION_DRAG_ENTERED

    进入目标View区域

    ACTION_DRAG_LOCATION

    停留目标View区域

    ACTION_DRAG_EXITED

    离开目标View区域

    ACTION_DROP

    释放拖拽操作

    ACTION_DRAG_ENDED

    结束拖拽操作

     

    有六种与拖放相关的事件,这些事件在DragEvent类中用六个常量表示,例如以下表所看到的:

    常量

    含义

    ACTION_DRAG_ENTERED

    当拖拽影子刚进入目标View对象的边框时,View对象的拖拽事件监听器会接收这样的事件操作类型。

    ACTION_DRAG_LOCATION

    在View对象收到一个

    ACTION_DRAG_ENTERED事件之后,而且拖拽影子依旧还在这个对象的边框之内时,这个View对象的拖拽事件监听器会接收这样的事件操作类型。

    ACTION_DRAG_EXITED

    View对象收到一个ACTION_DRAG_ENTERED和至少一个ACTION_DRAG_LOCATION事件之后。这个对象的事件监听器会接受这样的操作类型。

    ACTION_DROP

    当用户在一个View对象之上释放了拖拽影子,这个对象的拖拽事件监听器就会收到这样的操作类型。假设这个监听器在响应ACTION_DRAG_STARTED拖拽事件中返回了true。那么这样的操作类型仅仅会发送给一个View对象。假设用户在没有被注冊监听器的View对象上释放了拖拽影子,或者用户没有在当前布局的不论什么部分释放操作影子,这个操作类型就不会被发送。假设View对象成功的处理放下事件,监听器要返回true,否则应该返回false。

    ACTION_DRAG_ENDED

    当系统结束拖拽操作时,View对象拖拽监听器会接收这样的事件操作类型。这样的操作类型之前不一定是ACTION_DROP事件。假设系统发送了一个ACTION_DROP事件。那么接收ACTION_DRAG_ENDED操作类型不意味着放下操作成功了。

    监听器必须调用getResult()方法来获得响应ACTION_DROP事件中的返回值。

    假设ACTION_DROP事件没有被发送,那么getResult()会返回false。

    3、经常用法

    public int getAction ()

    作用

    返回拖拽的类型。该类型的可能值是以上的六个常量。

    public ClipData  getClipData()

    作用

    返回ClipData类型的对象,该对象中封装了被拖拽对象的数据

    提示

    ClipData对象在拖拽開始时创建。仅仅有DragEvent. ACTION_DROP事件发生时,getClipData()才干返回startDrag()中第一个參数代表的ClipData对象。

    public float getX()

    作用

    返回拖拽对象的横坐标

    public float getY()

    作用

    返回拖拽对象的纵坐标

    public Object getLocateState()

    作用

    获取startDrag()中的第三个參数

    二、【案例】

    Ø 目标

    在屏幕左上有一个时钟图片,屏幕下边有三个标签,分别代表卸载、启动和分享。如图4所看到的:


    长按时钟,在日志窗体显示“開始拖拽clock,拖动时钟时,如图-5所看到的:




    当拖动时钟进入到“启动”标签区域,在日志窗体显示:clock进入启动区,clock仍在启动区。入图-6所看到的


     



     

    当拖动时钟离开“启动”区域,在日志窗体显示:clock离开启动区。松开时钟将显示拖放结束。



    提示:

    当进入目标区域时,即使没有松手。仍会发生ACTION_DROP事件。因此在图-7中显示“启动clock”。

    当进入“卸载”、“分享”区域时。在日志窗体中也将显示类似图-6、图-7的信息。

    Ø 思路

    步骤1MainActivity实现拖放的相关接口

    public class MainActivity extends Activity implements OnDragListener,OnLongClickListener{

    步骤2、定义MainActivity的成员

    ImageView mivClock;

    TextView mtvUninstall,mtvStart,mtvShare;

    步骤3、初始化控件

    private void initView() {

    //创建显示时钟的控件

    mivClock=(ImageView) findViewById(R.id.ivClock);

    //设置时钟拖拽事件的响应

    mivClock.setOnDragListener(this);

    //设置长按时间的响应

    mivClock.setOnLongClickListener(this);

    //创建代表分享、启动和卸载的三个控件

    mtvShare=(TextView) findViewById(R.id.tvShare);

    mtvStart=(TextView) findViewById(R.id.tvStart);

    mtvUninstall=(TextView) findViewById(R.id.tvUninstall);

    //设置三个TextView响应拖拽事件的代码

    mtvShare.setOnDragListener(this);

    mtvStart.setOnDragListener(this);

    mtvUninstall.setOnDragListener(this);

    }

    步骤4、编写响应拖放事件的代码

        //响应拖拽事件

    @Override

    public boolean onDrag(View view, DragEvent event) {

    boolean result=true;

    //获取拖拽的动作类型值

    int action=event.getAction();

    switch (action) {

    case DragEvent.ACTION_DRAG_STARTED:

    if(view.getId()==R.id.ivClock){

    Log.i("main","開始拖拽clock");

    }

    break;

    case DragEvent.ACTION_DRAG_ENTERED:

    if(view.getId()==R.id.tvStart){

    Log.i("main","clock进入启动区");

    }

    break;

    case DragEvent.ACTION_DRAG_EXITED:

    if(view.getId()==R.id.tvStart){

    Log.i("main","clock离开启动区");

    }

    case DragEvent.ACTION_DRAG_LOCATION:

    if(view.getId()==R.id.tvStart){

    Log.i("main","clock仍在启动区");

    }

    case DragEvent.ACTION_DROP:

    if(view.getId()==R.id.tvShare){

    Log.i("main","分享clock");

    }else if(view.getId()==R.id.tvStart){

    Log.i("main","启动clock");

    }else if(view.getId()==R.id.tvUninstall){

    Log.i("main","卸载clock");

    }

    break;

    case DragEvent.ACTION_DRAG_ENDED:

    Log.i("main","拖拽结束。在drop事件之后发生");

    break;

    default:

    result=false;

    break;

    }

    return result;

    }

    步骤5、编写响应长按事件的代码

    //长按事件响应程序

    @Override

    public boolean onLongClick(View view) {

    //创建实现阴影的对象

    DragShadowBuilder builder=new DragShadowBuilder(view);

    /*開始拖拽并把view对象传递给系统。作为响应startDrag()方法的一部分,

     * 系统调用在View.DragShadowBuilder对象中定义的回调方法

     * 来获取拖拽影子。

     */

    view.startDrag(null, builder, null, 0);

    return true;

    }

    }




  • 相关阅读:
    hdu 4825 Xor Sum(01字典树模版题)
    poj 2778 DNA Sequence(ac自动机+矩阵快速幂)
    codeforces 626 G. Raffles(线段树+思维+贪心)
    hdu 2615 Division(暴力)
    hdu 6092 Rikka with Subset(多重背包)
    codeforces 688 E. The Values You Can Make(01背包+思维)
    JavaUtil smtp 邮件发送
    JavaUtil 处理Base64的图片上传
    Centos7 在apache+php7环境下 安装 Discuz!X3.4
    Centos7 安装 apache + php7.0 环境
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/7258815.html
Copyright © 2011-2022 走看看