由于工作需求,需要用到这种处理方法所以我就写了这个

废话不多说先看效果图

接下来就看代码吧 DragDropManager

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; /**
* 拖拽工具类
*/
public class DragDropManager implements View.OnTouchListener { /**
* View 集合
*/
private List<View> viewList; private static Activity mActivity;
private static DragDropManager mManager; private Map<View, ViewInfo> mViewMap; /**
* 窗口管理器,用于显示条目的快照
*/
private WindowManager mWindowManager; /**
* 窗口管理的布局参数
*/
private WindowManager.LayoutParams mWindowLayoutParams; /**
* 悬浮的imageView
*/
private ImageView mDragPhotoView;
private Bitmap mDragPhotoBitmap;
private float moveX;
private float moveY; private IDragDropListener listener; public DragDropManager() {
viewList = new ArrayList<>();
mViewMap = new HashMap<>();
} public static DragDropManager getInstance(Activity activity) {
mActivity = activity;
if (mManager == null) {
mManager = new DragDropManager();
}
return mManager;
} /**
* 绑定view
*/
public void bindView(View... views) {
viewList.clear();
for (View view : views) {
view.setOnTouchListener(this);
if(view instanceof TextView){
view.setOnClickListener(null);
}else if(view instanceof ViewGroup){
view.setOnClickListener(null);
}
viewList.add(view);
}
} /**
* 添加view
*
* @param views
*/
public void addView(View... views) {
for (View view : views) {
view.setOnTouchListener(this);
viewList.add(view);
}
} /**
* 设置监听事件
* @param listener
*/
public void setListener(IDragDropListener listener){
this.listener = listener;
} @Override
public boolean onTouch(View view, MotionEvent event) { int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
Log.i("tag", "生成图像");
//首先初始化每个控件的坐标信息
initViewLayout();
//判断出点击的是哪个控件 并悬浮出哪个控件
createDragPhotoView(view);
moveX = event.getX();
moveY = event.getY();
//回调监听
if(listener != null){
listener.startDragDrop(view.getId());
}
break;
case MotionEvent.ACTION_MOVE:
mWindowLayoutParams.x = (int) (mViewMap.get(view).x + (event.getX() - moveX));
mWindowLayoutParams.y = (int) (mViewMap.get(view).y + (event.getY() - moveY));
mWindowManager.updateViewLayout(mDragPhotoView, mWindowLayoutParams);
Log.i("tag", "移动图像 x:"+(view.getX() + (event.getX() - moveX))+" y:" + (view.getY() + (event.getY() - moveY)));
break;
case MotionEvent.ACTION_UP:
Log.i("tag", "去掉图像"); //
if(listener != null) {
for (View tempView : viewList) {
if (tempView.getId() != view.getId()) {
ViewInfo viewInfo = mViewMap.get(tempView);
if (event.getRawX() > viewInfo.x && event.getRawY() > viewInfo.y
&& event.getRawX() < (viewInfo.x + viewInfo.width) && event.getRawY() < (viewInfo.y + viewInfo.height)) {
listener.endDragDrop(view.getId(),tempView.getId());
break;
}
}
}
} // 移除快照
if (mDragPhotoView != null) {
mWindowManager.removeView(mDragPhotoView);
mDragPhotoView.setImageDrawable(null);
mDragPhotoBitmap.recycle();
mDragPhotoBitmap = null;
mDragPhotoView = null;
}
break;
}
return false;
} /**
* 初始化每个控件的坐标信息
*/
private void initViewLayout() {
mViewMap.clear();
int[] location = new int[2];
for (View view : viewList) {
view.getLocationInWindow(location);
ViewInfo viewInfo = new ViewInfo(view, location[0], location[1], view.getMeasuredHeight(), view.getMeasuredWidth());
mViewMap.put(view, viewInfo);
}
} /**
* 创建拖拽快照
*/
private void createDragPhotoView(View view) {
// 进行绘图缓存
view.setDrawingCacheEnabled(true);
// 提取缓存中的图片
mDragPhotoBitmap = Bitmap.createBitmap(view.getDrawingCache());
// 获取当前窗口管理器
mWindowManager = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE);
// 创建布局参数
mWindowLayoutParams = new WindowManager.LayoutParams();
mWindowLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mWindowLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
mWindowLayoutParams.gravity = Gravity.TOP | Gravity.START;
mWindowLayoutParams.format = PixelFormat.TRANSLUCENT; // 期望的图片为半透明效果,但设置其他值并没有看到不一样的效果
// 下面这些参数能够帮助准确定位到选中项点击位置
mWindowLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
mWindowLayoutParams.windowAnimations = 0; // 无动画
mWindowLayoutParams.alpha = 0.6f; // 微透明 mWindowLayoutParams.x = (int) mViewMap.get(view).x;
mWindowLayoutParams.y = (int) mViewMap.get(view).y;
mDragPhotoView = new ImageView(mActivity);
mDragPhotoView.setImageBitmap(mDragPhotoBitmap);
mWindowManager.addView(mDragPhotoView, mWindowLayoutParams);
} /**
* 监听接口
*/
public interface IDragDropListener{ /**
* 开始拖动
* @param startViewId 返回当前view的ID
*/
void startDragDrop(int startViewId); /**
* 结束拖动
* @param startViewId 返回当前view的ID
* @param endViewId 返回覆盖在某个view的ID
*/
void endDragDrop(int startViewId,int endViewId);
} /**
* 记录当前view的坐标和宽高信息
*/
class ViewInfo { private View view;
private float x;
private float y;
private float height;
private float width; public ViewInfo(View view, float x, float y, float height, float width) {
this.view = view;
this.x = x;
this.y = y;
this.height = height;
this.width = width;
}
}
}

使用方法

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast; public class MainActivity extends AppCompatActivity { private DragDropManager dragDropManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); TextView textView = findViewById(R.id.tvTitle);
TextView tegg = findViewById(R.id.tvTitlegg);
Button btnTuo = findViewById(R.id.btnTuo);
dragDropManager = DragDropManager.getInstance(this);
dragDropManager.bindView(textView,btnTuo,tegg);
dragDropManager.setListener(new DragDropManager.IDragDropListener() {
@Override
public void startDragDrop(int startViewId) {
Toast.makeText(MainActivity.this,"开始悬浮",0).show();
} @Override
public void endDragDrop(int startViewId, int endViewId) {
Toast.makeText(MainActivity.this,"开始悬浮 sID:" + startViewId + "//endID : " + endViewId,0).show();
}
}); textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this,"text dianji",0).show();
}
});
btnTuo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this,"btnTuo dianji",0).show();
}
});
}
}

代码demo
demo下载

参考博客:https://blog.csdn.net/a10615/article/details/51366459

View拖拽 自定义绑定view拖拽的工具类的更多相关文章

  1. 自定义响应结构 Json格式转换 工具类

    import java.util.List; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterx ...

  2. 让一个view 或者控件不支持拖拽

    让一个view 或者控件不支持拖拽: dragView.userInteractionEnabled = NO;

  3. 使用knockout-sortable实现对自定义菜单的拖拽排序

    在开始之前,照例,我们先看效果和功能实现. 关于自定义菜单的实现,这里就不多说了,需要了解的请访问:http://www.cnblogs.com/codelove/p/4838766.html 这里需 ...

  4. 自定义 Collection View 布局

    自定义 Collection View 布局 answer-huang 29 Mar 2014 分享文章 UICollectionView 在 iOS6 中第一次被引入,也是 UIKit 视图类中的一 ...

  5. iOS系列译文:自定义Collection View布局

    原文出处: Ole Begemann   译文出处: 黄爱武(@answer-huang).欢迎加入技术翻译小组. UICollectionView在iOS6中第一次被介绍,也是UIKit视图类中的一 ...

  6. 自定义Collection View布局

    转自answer-huang的博客 原文出自:Custom Collection View Layouts    UICollectionView在iOS6中第一次被介绍,也是UIKit视图类中的一颗 ...

  7. [asp.net mvc 奇淫巧技] 01 - 封装上下文 - 在View中获取自定义的上下文

    我们在asp.net 开发中已经封装了最强大的HttpContext,我们可以在HttpContext中可以获取到几乎任何想获取的东西,也可以在HttpContext写入需要返回客户端的信息.但是这些 ...

  8. ios --xib自定义,解决在导航栏不透明的情况下,自定义xib view高度被压缩64的问题

    在使用xib自定义view的时候,个人习惯性的直接使用xib中的约束,所以自然而然的要打开Autolayout.以前在使用的时候没有发现什么问题,最近项目中使用的时候突然发现在导航栏透明的情况下,出现 ...

  9. Android XML中引用自定义内部类view的四个why

    今天碰到了在XML中应用以内部类形式定义的自定义view,结果遇到了一些坑.虽然通过看了一些前辈写的文章解决了这个问题,但是我看到的几篇都没有完整说清楚why,于是决定做这个总结. 使用自定义内部类v ...

随机推荐

  1. WCF服务测试工具

    官网地址:http://www.wcfstorm.com/wcf/home.aspx WCFStorm Lite 来进行接口查看及调试,如下所示.

  2. winform treeview 绑定文件夹和文件

    转载:http://www.cnblogs.com/zhbsh/archive/2011/05/26/2057733.html #region treeview 绑定文件夹和文件 /// <su ...

  3. C/C++ Windows移植到Linux

    近期写了有关Socket的程序,需要从windows移植到linux.现把有用的东东收集整理记录下来. 1.头文件windows下winsock.h或winsock2.h:linux下netinet/ ...

  4. The method Inflate() in android

    Inflate() method can find out a layout defined by xml,as like the findViewById() method,but there ha ...

  5. ylbtech-LanguageSamples-Generics(泛型)

    ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-Generics(泛型) 1.A,示例(Sample) 返回顶部 “泛型”示例 (C#) ...

  6. Linux内核分析(九)——总结篇

    序:写在前面的话        本次内容作为Linux内核的总结内容,主要涉及对Linux系统的总体的一些理解,同时将之前的一些总结贴出来作为大家的一个索引,希望笔者的博客能对和笔者一样的菜鸟有一些帮 ...

  7. MongoDB分片集群新增分片(自用)

    机器IP为192.168.58.11,计划在上面新建两个分片并添加到原有分片集群中. 实施如下: 1.58.11创建mongodb文件夹 mkdir -p /opt/mongodb cd  /opt/ ...

  8. selenuim-webdriver注解之@FindBy、@FindBys、@FindAll的区别

    selenium-webdriver中获取页面元素的方式有很多,使用注解获取页面元素是其中一种途径, 方式有3种:@FindBy.@FindBys.@FindAll.下文对3中类型的区别和使用场景进行 ...

  9. C# Windows form application 播放小视频

    1. 下载direcly-show lib DLL点击打开链接 2. DxPlay.cs (能够在下载的样例中找到):    public class DxPlay : IDisposable { e ...

  10. selenium从入门到应用 - 8,selenium+testNG实现多线程的并发测试

    本系列所有代码 https://github.com/zhangting85/simpleWebtest本文将介绍一个Java+TestNG+Maven+Selenium的web自动化测试脚本环境下s ...