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 ...
随机推荐
- 数据访问与sql语句的管理(一)
在开发过程中数据访问是必不可少的.每个框架都会有自己数据访问机制.大家在一般的情况下会为自己的框架配备2套数据访问机制,ORM和DataHelper.当然,根据项目的需要有时候也可能只一种. 其实这2 ...
- MySQL第三方客户端工具
如前所述,MySQL是一个基于客户机--服务器的DBMS,因此,为了使用MySQl,你需要有一个客户机软件给MySQL提供要执行的命令.即你需要一个编写和测试MySQL脚本的工具. 1.MySQL命令 ...
- delphi执行cmd命令和bat文件
转载地址:http://blog.csdn.net/hutao1101175783/article/details/42807063 cmd:='echo d | Xcopy '+BasePath+' ...
- git新建和删除远程分支
创建远程分支: 新建本地分支 git checkout -b branch_name 推送到远程分支,分支名字和本地分支名字相同 git push origin branch_name:branch_ ...
- 原型设计工具——Axure
1,百度百科 http://baike.baidu.com/view/3332366.htm?from_id=5056136&type=syn&fromtitle=axure& ...
- poj_1284_原根
一開始看题的时候第一想法就是暴力,可是无奈数据量有点大,看了题解之后才知道原来牵扯到数论上的一个叫做原根的东西,这个题的题意就是,给你一个奇素数,问题他的原根有多少.依据初等数论上所说,此时牵扯到了三 ...
- Android平台Camera实时滤镜实现方法探讨(十)--代码地址以及简单介绍(20160118更新)
简单做了个相机和图片编辑模块,时间原因非常多功能还没有做.尚有BUG,见谅,将在以后抽时间改动 代码地址 PS:请点个Star^-^ --------------------------------- ...
- Timus Online Judge 1057. Amount of Degrees(数位dp)
1057. Amount of Degrees Time limit: 1.0 second Memory limit: 64 MB Create a code to determine the am ...
- 【Python3 爬虫】02_利用urllib.urlopen向百度翻译发送数据并返回结果
上一节进行了网页的简单抓取,接下来我们详细的了解一下两个重要的参数url与data urlopen详解 urllib.request.urlopen(url, data=None, [timeout, ...
- 通过Spring使用远程访问和web服务
http://docs.huihoo.com/spring/zh-cn/remoting.html Spring2 提供的remote包学习笔记