因为项目中有需要实现控件可任意拖拽的需求,所以简单写了个自定义OnTouchListener,以作抛砖引玉,欢迎大家提议反馈。

完整实现类如下,代码中有详细注释: 用户可以决定是否开启自动拖拽边缘功能,可以监听控件的拖拽和点击事件

public class OnDragTouchListener implements View.OnTouchListener {

private int mScreenWidth, mScreenHeight;//屏幕宽高

private float mOriginalX, mOriginalY;//手指按下时的初始位置

private float mDistanceX, mDistanceY;//记录手指与view的左上角的距离

private int left, top, right, bottom;

private OnDraggableClickListener mListener;

private boolean hasAutoPullToBorder;//标记是否开启自动拉到边缘功能

public OnDragTouchListener() {

}

public OnDragTouchListener(boolean isAutoPullToBorder) {

hasAutoPullToBorder = isAutoPullToBorder;

}

@Override

public boolean onTouch(final View v, MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

mScreenWidth = v.getResources().getDisplayMetrics().widthPixels;

mScreenHeight = v.getResources().getDisplayMetrics().heightPixels;

mOriginalX = event.getRawX();

mOriginalY = event.getRawY();

mDistanceX = event.getRawX() - v.getLeft();

mDistanceY = event.getRawY() - v.getTop();

break;

case MotionEvent.ACTION_MOVE:

left = (int) (event.getRawX() - mDistanceX);

top = (int) (event.getRawY() - mDistanceY);

right = left + v.getWidth();

bottom = top + v.getHeight();

if (left < 0) {

left = 0;

right = left + v.getWidth();

}

if (top < 0) {

top = 0;

bottom = top + v.getHeight();

}

if (right > mScreenWidth) {

right = mScreenWidth;

left = right - v.getWidth();

}

if (bottom > mScreenHeight) {

bottom = mScreenHeight;

top = bottom - v.getHeight();

}

v.layout(left, top, right, bottom);

break;

case MotionEvent.ACTION_UP:

//在拖动过按钮后,如果其他view刷新导致重绘,会让按钮重回原点,所以需要更改布局参数

ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) v.getLayoutParams();

startAutoPull(v, lp);

//如果移动距离过小,则判定为点击

if (Math.abs(event.getRawX() - mOriginalX) <

ScreenUtils.getPxFromDp(v.getResources(), 5) &&

Math.abs(event.getRawY() - mOriginalY) <

ScreenUtils.getPxFromDp(v.getResources(), 5)) {

if (mListener != null) {

mListener.onClick(v);

}

}

//消除警告

v.performClick();

break;

}

return true;

}

public OnDraggableClickListener getOnDraggableClickListener() {

return mListener;

}

public void setOnDraggableClickListener(OnDraggableClickListener listener) {

mListener = listener;

}

public boolean isHasAutoPullToBorder() {

return hasAutoPullToBorder;

}

public void setHasAutoPullToBorder(boolean hasAutoPullToBorder) {

this.hasAutoPullToBorder = hasAutoPullToBorder;

}

/**

* 开启自动拖拽

*

* @param v 拉动控件

* @param lp 控件布局参数

*/

private void startAutoPull(final View v, final ViewGroup.MarginLayoutParams lp) {

if (!hasAutoPullToBorder) {

v.layout(left, top, right, bottom);

lp.setMargins(left, top, 0, 0);

v.setLayoutParams(lp);

if (mListener != null) {

mListener.onDragged(v, left, top);

}

return;

}

//当用户拖拽完后,让控件根据远近距离回到最近的边缘

float end = 0;

if ((left + v.getWidth() / 2) >= mScreenWidth / 2) {

end = mScreenWidth - v.getWidth();

}

ValueAnimator animator = ValueAnimator.ofFloat(left, end);

animator.setInterpolator(new DecelerateInterpolator());

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

int leftMargin = (int) ((float) animation.getAnimatedValue());

v.layout(leftMargin, top, right, bottom);

lp.setMargins(leftMargin, top, 0, 0);

v.setLayoutParams(lp);

}

});

final float finalEnd = end;

animator.addListener(new AnimatorListenerAdapter() {

@Override

public void onAnimationEnd(Animator animation) {

super.onAnimationEnd(animation);

if (mListener != null) {

mListener.onDragged(v, (int) finalEnd, top);

}

}

});

animator.setDuration(400);

animator.start();

}

/**

* 控件拖拽监听器

*/

public interface OnDraggableClickListener {

/**

* 当控件拖拽完后回调

*

* @param v 拖拽控件

* @param left 控件左边距

* @param top 控件右边距

*/

void onDragged(View v, int left, int top);

/**

* 当可拖拽控件被点击时回调

*

* @param v 拖拽控件

*/

void onClick(View v);

}

}

后期有时间会做更多优化和扩展功能,如果有什么更好的方式或建议,欢迎大家反馈。

android 可拖拽控件,安卓实现任意控件view可拖拽,并监听拖拽和点击事件,可自动拉回屏幕边缘...相关推荐

  1. android列表项点击事件,Android 开发 tips(2):监听 Listview 列表项点击事件

    Android 开发 tips(2):监听 Listview 列表项点击事件 (这篇和上篇本来是应该一起写的,但是太过冗长,附链接:[SimpleAdapter 在 Listview 中的应用] ht ...

  2. Android按back后执行过程,安卓app测试获取接口返回数据,然后处理数据,放在一个button点击事件里面 执行顺序有问题?无法获取数据?...

    private JSONArray jsonArray; btn1.setOnClickListener(new View.OnClickListener() { @Override public v ...

  3. 安卓APP在运行时对全局进行网络状态监听的实现

    转载自:https://blog.51cto.com/wangjinchan/4752142 感谢博主:一粒程序米 分享 一.前言 怎么对APP进行全局的网络监听呢?仿照微信的无网状态下弹出的提示,应 ...

  4. 安卓传感器全解:注册、注销传感器、监听传感器,距离传感器、方向传感器、陀螺仪、加速计、磁场、气压传感器

    全栈工程师开发手册 (作者:栾鹏) 安卓教程全解 安卓传感器全解:注册.注销传感器.监听传感器.距离传感器.方向传感器.陀螺仪.加速计.磁场.气压传感器. 注册.注销.监听传感器 1.自定义传感器监听 ...

  5. jquery实现上下左右键盘监听_基于 jQuery 实现键盘事件监听控件

    最近项目里要做一个画板,需要对键盘事件进行监听,来进行诸如撤回.重做.移动.缩放等操作,因此顺手实现了一个键盘事件监听控件,期间略有收获,整理出来,希望对大家有所帮助,更希望能获得高手的指点. 1. ...

  6. 百度地图,开启marker点拖拽,并监听拖拽后的坐标位置

    有的网站可能让用户自己移动marker点选择位置   这个时候 需要就来了 开启marker点的拖拽还是很简单的哈 其实开启拖拽的也是  BMapGL 版本的地图  这点要记住哈    var mar ...

  7. Android移动开发之【通往安卓的神奇之旅】Senior VIew高级组件与onClickListener()再探索

    文章目录 1 setonClickListener() 2 button的OnClickListener的三种实现方法 3 VideoView 1 setonClickListener() setOn ...

  8. android 监听安装来源_Flutter插件开发之APK自动安装

    点击上方的终端研发部,右上角选择"设为星标" 每日早9点半,技术文章准时送上 公众号后台回复"学习",获取作者独家秘制精品资料 往期文章 记五月的一个Andro ...

  9. Android viewpager 嵌套 viewpager滑动 点击事件冲突解决方案

    为了解决这个问题.可以自定义viewpager,然后在里面监听首饰,自定义点击事件 package com.hpuvoice.view;import android.content.Context; ...

  10. 详细讲解安卓截屏监听操作

    需求 项目中有时会遇到监听用户截屏操作的需求,应用场景也比较丰富. eg. 1: 某个隐私页面禁止截屏,当发现用户截屏后,删除该截屏文件: eg. 2: 当用户截屏时,可能是需要进行分享,意见反馈等操 ...

最新文章

  1. 利用 Java dump 进行 JVM 故障诊断
  2. 服务器重启后启动Docker命令
  3. 大数据的说法 正确的是_前端测试题:(解析)用于播放音频文件的正确HTML5元素是?...
  4. JAVA数组扁平化整合_JS数组扁平化(flat)方法总结详解
  5. mysql 日期和时间类型
  6. oracle10g中获得可更新的(修改、增加等) ResultSet
  7. 灰色关联分析_R语言使用灰色关联分析(Grey Relation Analysis,GRA)中国经济社会发展指标...
  8. git如何查看和切换账号
  9. win10wifi多了数字_win10系统电脑查看wifi密码是多少的方法
  10. CVPR 2018:阿里提出新零样本学习方法,有效解决偏置问题
  11. Windows7系统无损分区的教程
  12. PMP知识点总结-自由时差与总时差
  13. 【JVM】17、垃圾回收器
  14. Windows Installer服务总是自动关闭导致无法安装在win10上安装英伟达显卡驱动的解决方案...
  15. 【光纤专题】单模光纤和多模光纤有哪些不同之处?《建议收藏》
  16. 小众软件android,应用专题 - 这些小众软件,满足你文艺不甘寂寞的心|微信安卓版7.0内测来啦 - Android 应用 - 生活 - 【最美应用】...
  17. 公安大数据应用之情报分析与关联挖掘
  18. 微信群里的这几类人,真让人想打他
  19. c语言编程怎么样,C语言怎么样,好学吗?
  20. 英语之境(chapter two)

热门文章

  1. django打开html页面跳转,django创建最简单HTML页面跳转方法
  2. Android截屏的几种方法
  3. mysql substr 中文乱码_substr()乱码
  4. 读写器APDU指令读写FM1208CPU卡
  5. 51单片机驱动8位数码管(74HC595驱动)滚动显示
  6. TIA WinCC Professional入门经典(1) 组态第一个WinCC Professional项目
  7. React脚手架配置代理解决跨域
  8. 通过eslint统一前端IDE的编码风格,避免git冲突
  9. 十大排序算法(附动态图解)- Java版
  10. Delphi 技术的优缺点与应用