Android开发:拖拽

google官网的training和API两个地方都提到了拖拽的实现,两种方法不太一样。

方法一

training(https://developer.android.com/training/gestures/scale.html)中提到的方法是监听onTouchEvent,在ACTION_DOWN的时候记录位置,在ACTION_MOVE的时候获取坐标,改变拖拽的控件位置。

方法二

在android3.0及以上可以使用View.OnDragListener。

下面是我写的简单的demo:

activity_drag_demo.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_drag_demo"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.topsports.testapplication.DragDemoActivity">
<ImageView
    android:id="@+id/imageView"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="@drawable/c1"/>

    <FrameLayout
        android:background="#c7f6ff"
        android:layout_width="500dp"
        android:layout_height="500dp"
        android:id="@+id/content_fragment"
        android:layout_alignParentBottom="true"></FrameLayout>

    <FrameLayout
        android:background="#dce9c1"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:id="@+id/content_fragment2"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"></FrameLayout>

</RelativeLayout>
在官网示例基础上修改的DragDemoActivity:package com.topsports.testapplication;
import android.content.ClipData;
import android.content.ClipDescription;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.DragEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toast;

public class DragDemoActivity extends AppCompatActivity {

    private ImageView imageView;

    private FrameLayout frameLayout;
    private FrameLayout frameLayout2;

    private static final String IMAGEVIEW_TAG = "icon bitmap";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_drag_demo);

        imageView=(ImageView)findViewById(R.id.imageView);
        frameLayout=(FrameLayout)findViewById(R.id.content_fragment);
        frameLayout2=(FrameLayout)findViewById(R.id.content_fragment2);

        imageView.setTag(IMAGEVIEW_TAG);

        imageView.setOnLongClickListener(new View.OnLongClickListener() {

             public boolean onLongClick(View v) {

                 v.getBackground().setAlpha(100);

                 ClipData.Item item = new ClipData.Item(v.getTag().toString());

ClipData dragData = new ClipData(v.getTag().toString(),new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN},item);

                 // Instantiates the drag shadow builder.
                 View.DragShadowBuilder myShadow = new View.DragShadowBuilder(v);
                 v.startDrag(dragData,  // the data to be dragged
                         myShadow,  // the drag shadow builder
                         null,      // no need to use local data
                         0          // flags (not currently used, set to 0)
                 );

                 return true;

             }
        });

        frameLayout.setOnDragListener(new myDragEventListener());
        frameLayout2.setOnDragListener(new myDragEventListener());

        imageView.setOnDragListener(new myDragEventListener());

    }protected class myDragEventListener implements View.OnDragListener {

        // This is the method that the system calls when it dispatches a drag event to the
        // listener.
        public boolean onDrag(View v, DragEvent event) {

            // Defines a variable to store the action type for the incoming event
            final int action = event.getAction();

            // Handles each of the expected events
            switch(action) {

                case DragEvent.ACTION_DRAG_STARTED:

                    // Determines if this View can accept the dragged data
                    if (event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {

                        v.invalidate();

                        // returns true to indicate that the View can accept the dragged data.
                        return true;

                    }

                    // Returns false. During the current drag and drop operation, this View will
                    // not receive events again until ACTION_DRAG_ENDED is sent.
                    return false;

                case DragEvent.ACTION_DRAG_ENTERED:

                    // Applies a green tint to the View. Return true; the return value is ignored

                    // Invalidate the view to force a redraw in the new tint
                    v.invalidate();

                    return true;

                case DragEvent.ACTION_DRAG_LOCATION:

                    // Ignore the event
                    return true;

                case DragEvent.ACTION_DRAG_EXITED:

                    // Re-sets the color tint to blue. Returns true; the return value is ignored.

                    // Invalidate the view to force a redraw in the new tint
                    v.invalidate();

                    return true;

                case DragEvent.ACTION_DROP:

                    // Gets the item containing the dragged data
                    ClipData.Item item = event.getClipData().getItemAt(0);

                    // Gets the text data from the item.
                    String dragData = item.getText().toString();

                    // Displays a message containing the dragged data.
                    Toast.makeText(DragDemoActivity.this, "Dragged data is " + dragData, Toast.LENGTH_LONG).show();

                    // Turns off any color tints
                    if(v instanceof FrameLayout){
                        ((ViewGroup)imageView.getParent()).removeView(imageView);
                        ((FrameLayout)v).addView(imageView);
                    }
                    // Invalidates the view to force a redraw
                    v.invalidate();

                    // Returns true. DragEvent.getResult() will return true.
                    return true;

                case DragEvent.ACTION_DRAG_ENDED:

                    // Turns off any color tinting

                    // Invalidates the view to force a redraw
                    v.invalidate();

                    // Does a getResult(), and displays what happened.
                    if (event.getResult()) {
                        Toast.makeText(DragDemoActivity.this, "The drop was handled.", Toast.LENGTH_LONG).show();

                    } else {
                        Toast.makeText(DragDemoActivity.this, "The drop didn‘t work.", Toast.LENGTH_LONG).show();

                    }
                    imageView.getBackground().setAlpha(255);
                    // returns true; the value is ignored.
                    return true;

                // An unknown action type was received.
                default:
                    Log.e("DragDrop Example","Unknown action type received by OnDragListener.");
                    break;
            }

            return false;
        }
    }
}

实现的是将图片拖进两个layout中,并在两个layout间来回拖动。

代码做简单的解释

在长按imageview的时候开始拖拽事件

ClipData.Item item = new ClipData.Item(v.getTag().toString());

ClipData dragData = new ClipData(v.getTag().toString(),new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN},item);

这两句是为拖动的view创建传递的数据(可以省略)

View.DragShadowBuilder myShadow = new View.DragShadowBuilder(v)

这句根据imageview(v)创建一个拖拽的阴影,就像在桌面上拖动应用图标一样,产生一个view的图像副本,产生拖动效果。

frameLayout.setOnDragListener(new myDragEventListener());

frameLayout2.setOnDragListener(new myDragEventListener());

imageView.setOnDragListener(new myDragEventListener());

设置拖拽的事件监听(拖动的对象和被放置的对象)实现View.OnDragListener的onDrag方法,判断event.getAction()的值进行不同的操作。

 

时间: 2024-08-11 08:59:08

Android开发:拖拽的相关文章

android可拖拽item的ListView--DragListVie

本博客原创,转载请标明 原文出处:http://blog.csdn.net/sql26/article/details/52252644 1.概述 在android项目开发中,需求对ListView中的商品item进行拖拽重新排序,网上看了一些帖子做的效果不错,就是代码不开源只写了思路,要么代码没注释,还不如自己写一个.. 2.效果图: 3.原理: 1.在touch事件里面通过ListView的pointToPosition(x, y)方法拿到当前点击的item的position: 2.根据当前

HTML5开发 拖拽文件上传

Drag&Drop 拖拽功能的处理 关于HTML5拖拽文件上传,其实国外已经有很多网站有这样的应用,最早推出拖拽上传应用的是 Gmail,它支持标准浏览器下拖拽本地文件到浏览器中作为邮件的附件发送,但其实现在利用HTML5的功能实现,主要借助于新版支持的浏览器来实现,IE还是弱很多. 拖拽上传应用主要使用了以下 HTML5技术: Drag&Drop : HTML5基于拖拽的事件机制.File API : 可以很方便的让 Web 应用访问文件对象,File API 包括FileList.Bl

Android Launcher拖拽事件详解【android4.0--Launcher系列二】

AndroidICS4.0版本的launcher拖 拽的流程,基本和2.3的相似.就是比2.3写的封装的接口多了一些,比如删除类的写法就多了个类.等等.4.0的改变有一些,但是不是特别大.这个月一 直在改动Launcher的缩略图的效果,4.0的缩略图的功能没有实现,还得从2.3的Launcher中摘出来.通过做这个缩略图对Launcher 的模块有一点点了解,拿来分享一下Launcher拖拽的工作流程.有图有真相!   (1) 先来看看类之间的继承关系      图(1)  (2)再来看看La

android五子棋游戏、资讯阅读、大学课程表、地图拖拽检测、小说搜索阅读app等源码

Android精选源码 Android 自动生成添加控件 android旋转动画.圆形进度条组合效果源码 一款很强的手机五子棋app源码 android地图拖拽区域检测效果源码 实现Android大学课表效果APP源码 android完全免费的小说搜索阅读app 一个互联网资讯阅读平台和良好的阅读体验的App Android优质博客 Android中高效的显示图片Bitmap的内存模型 相对于文字来说,图片的表达更直接.更有冲击力.更容易吸引用户的眼球.设计师们也理所当然的喜欢用图片来传达信息.

android开发常用组件和第三方库(二)

TimLiu-Android 自己总结的Android开源项目及库. github排名 https://github.com/trending, github搜索:https://github.com/search 目录 UI UI 卫星菜单 节选器 下拉刷新 模糊效果 HUD与Toast 进度条 UI其它 动画 网络相关 响应式编程 地图 数据库 图像浏览及处理 视频音频处理 测试及调试 动态更新热更新 消息推送 完整项目 插件 出名框架 其他 好的文章 收集android上开源的酷炫的交互动

Java实现拖拽上传

原文:http://www.open-open.com/code/view/1437358795584 在项目开发中由于实际需求,需要开发拖拽上传的功能,ok! 先看效果图: jsp上传前端代码: <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html>

android开发游记:SpringView 下拉刷新的高效解决方案,定制你自己风格的拖拽页面

关于下拉刷新/上拉加载更多的解决方案网上已经有很多了,浏览了目前主流的下拉控件比如PullToRefresh库等,第一:大多数实现库都难以进行动画和样式的自定义.第二:不能很好的兼容多种滚动控件,它们都对listView.RecyclerView等进行了不同程度的重新实现,你在项目中就得使用库提供的PullToRefreshListView.PullToRefreshRecyclerView等来代替源生的listView.RecyclerView等,这样的方式其实并不好,随着android版本的

android开发游记:ItemTouchHelper 使用RecyclerView打造可拖拽的GridView

以下是RecyclerView结合ItemTouchHelper实现的列表和网格布局的拖拽效果. 效果图例如以下:(gif图有点顿卡,事实上执行是非常流畅的) demo下载地址: DragRecyclerView 怎样实现 那么是怎样实现的呢?主要就要使用到ItemTouchHelper ,ItemTouchHelper 是support-v7包中加入的一个帮助开发人员处理拖拽和滑动的实现类,它能够让你非常easy实现側滑删除.拖拽的功能. 我们仅仅须要实例化一个ItemTouchHelper.

Android中GridView拖拽的效果

最 近看到联想,摩托罗拉等,手机launcher中有个效果,进入mainmenu后,里面的应用程序的图标可以拖来拖去,所以我也参照网上给的代码,写了 一个例子.还是很有趣的,实现的流畅度没有人家的那么好,我只是模仿这种效果,我写的这个拖拽是两个图标之间进行交换,所以,当从一行的某个位置,换到下 一行的另一列的时候,发现有好几个图标都改变位置了,因为是相邻两个交换位置,所以每经过相邻的图标的时候都改变位置.先弄个雏形,以后再更新优化. 转载请标明出处:http://blog.csdn.net/wd