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 ...
随机推荐
- Mac下Git的安装和卸载
1.安装最新版本:https://git-scm.com/download/mac,下载pkg进行安装 2.卸载:运行/usr/local/git/uninstall.sh
- MooseFS分布式文件系统介绍及安装教程详解
MFS系统由4个部分构成:master.metalogger.chunkserver.client. 1.Master —— mfs的大脑,记录着管理信息,比如:文件大小,存储的位置,份数等,和inn ...
- iOS开发- 自己主动消失的弹出框
- (void)timerFireMethod:(NSTimer*)theTimer//弹出框 { UIAlertView *promptAlert = (UIAlertView*)[theTimer ...
- SVN服务的部署及使用
环境说明 系统版本 CentOS 7.2 x86_64 SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是 ...
- hbase shell删除键不听使唤
用Xshell登陆linux主机后,在hbase shell下死活不能使用backspace和delete删除误输的指令,只得不停退出,重登,仔细输..又错了,再退出,再登,仔细输...又错了...又 ...
- Node.js 访问https网站
源码: //==================================================== // 访问https://www.zhihu.com/得到pagecode // ...
- WRTNode(MT7620n)USB启动总结
一.改动mt7620.dtsi,去掉默认的bootargs,kernel_menuconfig取消buildin的command line 二.kernel_menuconfig增加scsi驱动.US ...
- 记录一个奇妙的Bug, -1 >= 2 ?
直接上代码: #include <iostream> #include <vector> using namespace std; int main() { vector< ...
- Django——如何处理请求(URL配置和视图)
URLconfig—— 为了绑定视图函数和URL,我们使用URLconf. URLconf 就像是 Django 所支撑网站的目录. 它的本质是 URL 模式以及要为该 URL 模式调用的视图函数之间 ...
- 解决Odoo访问fonts.googleapis.com导致速度慢的问题
Odoo中有些css文件引用了谷歌字体,但因为谷歌服务器被墙,导致部分页面加载受影响. 解决方法如下: 360网站卫士常用前端公共库CDN服务把谷歌字体库都存到它的CDN上了,因此我们只需把样式表中谷 ...