当前位置: 首页 > article >正文

安卓悬浮可跳动自动吸附可设置不同的吸附距离view

 DraggableImageView.java
/**
 *
 * @author 悬浮拖到可设置间距view
 * @author 主要用于 客服组件
 */
public class DraggableImageView extends ImageView {
    private float dX;// X轴偏移量
    private float dY;// Y轴偏移量
    private int screenWidth;// 屏幕宽度
    private int screenHeight;// 屏幕高度
    private int topMargin;// 上边距
    private int bottomMargin;// 下边距
    private int leftMargin;// 左边距
    private int rightMargin;// 右边距

    public DraggableImageView(Context context) {
        super(context);
        init(context);
    }

    public DraggableImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public DraggableImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    /**
     * 初始化
     * @param context
     */
    private void init(Context context) {
        int marginDp = 16;
        topMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, marginDp, context.getResources().getDisplayMetrics());
        bottomMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, marginDp, context.getResources().getDisplayMetrics());
        leftMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, marginDp, context.getResources().getDisplayMetrics());
        rightMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, marginDp, context.getResources().getDisplayMetrics());
    }

    public void setTopMargin(int marginDp) {
        topMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, marginDp, getContext().getResources().getDisplayMetrics());
    }

    public void setBottomMargin(int marginDp) {
        bottomMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, marginDp, getContext().getResources().getDisplayMetrics());
    }

    public void setLeftMargin(int marginDp) {
        leftMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, marginDp, getContext().getResources().getDisplayMetrics());
    }

    public void setRightMargin(int marginDp) {
        rightMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, marginDp, getContext().getResources().getDisplayMetrics());
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        screenWidth = ((View) getParent()).getWidth();
        screenHeight = ((View) getParent()).getHeight();
    }

    // 处理触摸事件
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                dX = getX() - event.getRawX();
                dY = getY() - event.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                float newX = event.getRawX() + dX;
                float newY = event.getRawY() + dY;
                newX = Math.max(leftMargin, Math.min(newX, screenWidth - getWidth() - rightMargin));
                newY = Math.max(topMargin, Math.min(newY, screenHeight - getHeight() - bottomMargin));

                setX(newX);
                setY(newY);
                break;
            case MotionEvent.ACTION_UP:
                float centerX = getX() + getWidth() / 2;
                float centerY = getY() + getHeight() / 2;

                // 计算到各个水平边缘的距离
                float leftDistance = centerX - leftMargin;
                float rightDistance = screenWidth - getWidth() - rightMargin - centerX;

                // 找到最近的水平边缘
                if (leftDistance <= rightDistance) {
                    animate().x(leftMargin).y(centerY - getHeight() / 2).start();
                } else {
                    animate().x(screenWidth - getWidth() - rightMargin).y(centerY - getHeight() / 2).start();
                }
                break;
            default:
                return false;
        }
        return true;
    }
}

设置吸附边距如下

 

xml布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.yourpackage.DraggableImageView
        android:id="@+id/draggableImageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/your_image"
        android:layout_centerInParent="true"/>
</RelativeLayout>

效果图如下:

 


http://www.kler.cn/a/471429.html

相关文章:

  • 基于SpringBoot实现的保障性住房管理系统
  • open61499符合新型工业控制测试要求吗
  • libaom 源码分析线程结构
  • VS2022 C#创建Com组件和调用
  • 字玩FontPlayer开发笔记4 性能优化 首屏加载时间优化
  • SSL,TLS协议分析
  • 【机器学习】机器学习的基本分类-自监督学习-自回归方法(Autoregressive Methods)
  • 计算机网络——数据链路层-流量控制和可靠传输
  • Docker - 6.设置SSH自动启动并使用root登录
  • 【工业场景】用YOLOv8实现工业配电柜开关状态识别
  • 鸿蒙ArkUI实现部门树列表
  • 入门嵌入式(四)——IICOLED
  • 用JAVA 源码角度看 客户端请求服务器流程中地址是域名情况下解析域名流程
  • CSS语言的文件操作
  • excel如何将小数转换为百分比
  • lec1-计算机概述
  • 深度学习:探索人工智能的未来
  • 深入解析 Python 中的函数也是对象及其内存分析
  • springboot+vue使用easyExcel实现导出功能
  • 小兔鲜儿:底部区域(头尾在每个页面都有,样式写在common.css中)
  • HTTP/HTTPS ①-代理 || URL || GET/POST || CDN
  • 利用Python爬虫获取淘宝店铺所有商品信息案例指南
  • 设计模式(1)——面向对象和面向过程,封装、继承和多态
  • 使用 Spring 的 事件发布和监听机制,结合异步执行 的功能达到方法异步执行
  • <style lang=“scss“ scoped>: 这是更常见的写法,也是官方文档中推荐的写法
  • 如何在读博过程中缓解压力