View拖拽 自定义绑定view拖拽的工具类
由于工作需求,需要用到这种处理方法所以我就写了这个
废话不多说先看效果图
接下来就看代码吧 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拖拽的工具类的更多相关文章
- 自定义响应结构 Json格式转换 工具类
import java.util.List; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterx ...
- 让一个view 或者控件不支持拖拽
让一个view 或者控件不支持拖拽: dragView.userInteractionEnabled = NO;
- 使用knockout-sortable实现对自定义菜单的拖拽排序
在开始之前,照例,我们先看效果和功能实现. 关于自定义菜单的实现,这里就不多说了,需要了解的请访问:http://www.cnblogs.com/codelove/p/4838766.html 这里需 ...
- 自定义 Collection View 布局
自定义 Collection View 布局 answer-huang 29 Mar 2014 分享文章 UICollectionView 在 iOS6 中第一次被引入,也是 UIKit 视图类中的一 ...
- iOS系列译文:自定义Collection View布局
原文出处: Ole Begemann 译文出处: 黄爱武(@answer-huang).欢迎加入技术翻译小组. UICollectionView在iOS6中第一次被介绍,也是UIKit视图类中的一 ...
- 自定义Collection View布局
转自answer-huang的博客 原文出自:Custom Collection View Layouts UICollectionView在iOS6中第一次被介绍,也是UIKit视图类中的一颗 ...
- [asp.net mvc 奇淫巧技] 01 - 封装上下文 - 在View中获取自定义的上下文
我们在asp.net 开发中已经封装了最强大的HttpContext,我们可以在HttpContext中可以获取到几乎任何想获取的东西,也可以在HttpContext写入需要返回客户端的信息.但是这些 ...
- ios --xib自定义,解决在导航栏不透明的情况下,自定义xib view高度被压缩64的问题
在使用xib自定义view的时候,个人习惯性的直接使用xib中的约束,所以自然而然的要打开Autolayout.以前在使用的时候没有发现什么问题,最近项目中使用的时候突然发现在导航栏透明的情况下,出现 ...
- Android XML中引用自定义内部类view的四个why
今天碰到了在XML中应用以内部类形式定义的自定义view,结果遇到了一些坑.虽然通过看了一些前辈写的文章解决了这个问题,但是我看到的几篇都没有完整说清楚why,于是决定做这个总结. 使用自定义内部类v ...
随机推荐
- 集合视图UICollectionView 介绍及其示例程序
UICollectionView是一种新的数据展示方式,简单来说可以把它理解成多列的UITableView.如果你用过iBooks的话,可 能你还对书架布局有一定印象,一个虚拟书架上放着你下载和购买的 ...
- mipmap of unity
遇到个奇怪的事情 mipmap generation 0级不压缩 1级 4个合1个 在unity里面 明显开了 mipmapgenerate之后 level0变糊了 ================ ...
- 理解JS中的模块规范(CommonJS,AMD,CMD)
随着互联网的飞速发展,前端开发越来越复杂.本文将从实际项目中遇到的问题出发,讲述模块化能解决哪些问题,以及如何使用 Sea.js 进行前端的模块化开发. 恼人的命名冲突 我们从一个简单的习惯出发.我做 ...
- Java源码阅读PriorityQueue
1类签名与简介 public class PriorityQueue<E> extends AbstractQueue<E> implements java.io.Serial ...
- 使用网桥模式(bridge networking mode)配置KVM-QUME虚拟机网络
(1)linux要工作在网桥模式,所以必须安装两个RPM包.即:bridge-utils和tunctl.它们提供所需的brctl.tunctl命令行工具.能够使用yum在线安装: [root@serv ...
- C++ 字符串转化成浮点型
第一种: char szString[] = "3.1415926535898"; double db1; db1 = atof(szString); printf(" ...
- tcp/ip--百度百科
Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协议.Inter ...
- measureChildren的工作原理
无论是在重写View还是ViewGroup的时候,尤其是ViewGrop的时候,往往不可避免的重写onMeasure方法,我们一定会调用setMeasuredDimension()将测量好的宽高值传递 ...
- JavaScript | 基础表单验证(纯Js)
———————————————————————————————————————————— 基础表单验证(纯js) - - - - - - - - - - - - - - - - - - - - - - ...
- 改动图片exif信息
我们先了解一下EXIF: EXIF能够附加于JPEG.TIFF.RIFF等文件之中.为其添加有关数码相机拍摄信息的内容和索引图或图像处理软件的版本号信息. 全部的JPEG文件以字符串"0xF ...