自定义 浮动button 自动靠边 附加收缩功能

2024-08-31 09:38

本文主要是介绍自定义 浮动button 自动靠边 附加收缩功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

悬浮按钮可全屏滑动,左吸附、右吸附,外加右吸附后2秒后收缩功能,收缩完点击弹出 ,先看下效果,右吸附和收缩:

左吸附部分注释掉了,可根据实际情况修改使用 

package com.example.test1.customView;import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.widget.Button;import androidx.annotation.NonNull;import com.example.test1.utils.LoggUtils;/*** Created by WJY.* Date: 2021/3/10* Time: 15:10* Description: 自定义 浮动button 自动靠边*/
@SuppressLint("AppCompatCustomView")
public class DragFloatActionButton extends Button {private int parentHeight;private int parentWidth;private int lastX;private int lastY;private boolean isDrag;Handler mHndler = new Handler(){@Overridepublic void handleMessage(@NonNull Message msg) {super.handleMessage(msg);switch (msg.what){case 0:animate().setInterpolator(new DecelerateInterpolator()).setDuration(200).xBy((float) (parentWidth - getWidth() - getX() + (0.7*getWidth()))).start();break;}}};public DragFloatActionButton(Context context) {super(context);}public DragFloatActionButton(Context context, AttributeSet attrs) {super(context, attrs);}public DragFloatActionButton(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}@Overridepublic boolean onTouchEvent(MotionEvent event) {int rawX = (int) event.getRawX();int rawY = (int) event.getRawY();switch (event.getAction() & MotionEvent.ACTION_MASK) {case MotionEvent.ACTION_DOWN:setPressed(true);isDrag = false;getParent().requestDisallowInterceptTouchEvent(true);lastX = rawX;lastY = rawY;ViewGroup parent;if (getParent() != null) {parent = (ViewGroup) getParent();parentHeight = parent.getHeight();parentWidth = parent.getWidth();}break;case MotionEvent.ACTION_MOVE:if (parentHeight <= 0 || parentWidth == 0) {isDrag = false;break;} else {isDrag = true;}int dx = rawX - lastX;int dy = rawY - lastY;//这里修复一些华为手机无法触发点击事件int distance = (int) Math.sqrt(dx * dx + dy * dy);if (distance == 0) {isDrag = false;break;}float x = getX() + dx;float y = getY() + dy;//检测是否到达边缘 左上右下x = x < 0 ? 0 : x > parentWidth - getWidth() ? parentWidth - getWidth() : x;y = getY() < 0 ? 0 : getY() + getHeight() > parentHeight ? parentHeight - getHeight() : y;setX(x);setY(y);lastX = rawX;lastY = rawY;Log.e("Log", "isDrag=" + isDrag + "getX=" + getX() + ";getY=" + getY() + ";parentWidth=" + parentWidth);break;case MotionEvent.ACTION_UP:if (!isNotDrag()) {//恢复按压效果setPressed(false);//靠右吸附animate().setInterpolator(new DecelerateInterpolator()).setDuration(200).xBy(parentWidth - getWidth() - getX()).start();LoggUtils.e("靠右吸附","getX()="+getX()+"---getWidth()="+getWidth());new Thread(new Runnable() {@Overridepublic void run() {try {Thread.sleep(2000);mHndler.sendEmptyMessage(0);} catch (InterruptedException e) {e.printStackTrace();}}}).start();//下面注释掉的是靠左和靠右吸附两种情况,可根据实际使用修改
//                    if (rawX >= parentWidth / 2) {
//                        //靠右吸附
//                        animate().setInterpolator(new DecelerateInterpolator())
//                                .setDuration(200)
//                                .xBy(parentWidth - getWidth() - getX())
//                                .start();
//                        LoggUtils.e("靠右吸附","getX()="+getX()+"---getWidth()="+getWidth());
//                        new Thread(new Runnable() {
//                            @Override
//                            public void run() {
//                                try {
//                                    Thread.sleep(2000);
//                                    mHndler.sendEmptyMessage(0);
//                                } catch (InterruptedException e) {
//                                    e.printStackTrace();
//                                }
//                            }
//                        }).start();
//                    } else {
//                        //靠左吸附
//                        ObjectAnimator oa = ObjectAnimator.ofFloat(this, "x", getX(), 0);
//                        oa.setInterpolator(new DecelerateInterpolator());
//                        oa.setDuration(200);
//                        oa.start();
//                        LoggUtils.e("靠左吸附","getX()="+getX()+"---getWidth()="+getWidth());
//                    }}break;}//如果是拖拽则消耗事件,否则正常传递即可。return !isNotDrag() || super.onTouchEvent(event);}private boolean isNotDrag() {return !isDrag && (getX() == 0 || (getX() == parentWidth - getWidth()));}
}

在布局中使用,就相当与一个控件

<com.example.test1.customView.DragFloatActionButtonandroid:id="@+id/floatBtn"android:layout_width="@dimen/dimen_81dp"android:layout_height="@dimen/dimen_40dp"android:background="@drawable/bg_blue_leftcorner"android:drawableLeft="@mipmap/icon_left"android:paddingLeft="@dimen/dimen_14dp"android:paddingRight="@dimen/dimen_14dp"android:text="吸附"android:textColor="@color/white"android:textSize="14sp"android:layout_gravity="bottom|right"android:visibility="visible"/>

其中用到的一个button背景是自定义的一个文件bg_blue_leftcorner.xml,也可根据实际需求来写

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"><solid android:color="@color/blue_10" /><corners android:bottomLeftRadius="@dimen/dimen_20dp"android:topLeftRadius="@dimen/dimen_20dp"/></shape>

到此,一个可吸附的悬浮按钮就完成了,不足之处欢迎指正。

这篇关于自定义 浮动button 自动靠边 附加收缩功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1123542

相关文章

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

Qt使用QSqlDatabase连接MySQL实现增删改查功能

《Qt使用QSqlDatabase连接MySQL实现增删改查功能》这篇文章主要为大家详细介绍了Qt如何使用QSqlDatabase连接MySQL实现增删改查功能,文中的示例代码讲解详细,感兴趣的小伙伴... 目录一、创建数据表二、连接mysql数据库三、封装成一个完整的轻量级 ORM 风格类3.1 表结构

SpringBoot+Docker+Graylog 如何让错误自动报警

《SpringBoot+Docker+Graylog如何让错误自动报警》SpringBoot默认使用SLF4J与Logback,支持多日志级别和配置方式,可输出到控制台、文件及远程服务器,集成ELK... 目录01 Spring Boot 默认日志框架解析02 Spring Boot 日志级别详解03 Sp

mysql表操作与查询功能详解

《mysql表操作与查询功能详解》本文系统讲解MySQL表操作与查询,涵盖创建、修改、复制表语法,基本查询结构及WHERE、GROUPBY等子句,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随... 目录01.表的操作1.1表操作概览1.2创建表1.3修改表1.4复制表02.基本查询操作2.1 SE

浏览器插件cursor实现自动注册、续杯的详细过程

《浏览器插件cursor实现自动注册、续杯的详细过程》Cursor简易注册助手脚本通过自动化邮箱填写和验证码获取流程,大大简化了Cursor的注册过程,它不仅提高了注册效率,还通过友好的用户界面和详细... 目录前言功能概述使用方法安装脚本使用流程邮箱输入页面验证码页面实战演示技术实现核心功能实现1. 随机

Golang如何用gorm实现分页的功能

《Golang如何用gorm实现分页的功能》:本文主要介绍Golang如何用gorm实现分页的功能方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录背景go库下载初始化数据【1】建表【2】插入数据【3】查看数据4、代码示例【1】gorm结构体定义【2】分页结构体

Java实现自定义table宽高的示例代码

《Java实现自定义table宽高的示例代码》在桌面应用、管理系统乃至报表工具中,表格(JTable)作为最常用的数据展示组件,不仅承载对数据的增删改查,还需要配合布局与视觉需求,而JavaSwing... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

一文详解Java Stream的sorted自定义排序

《一文详解JavaStream的sorted自定义排序》Javastream中的sorted方法是用于对流中的元素进行排序的方法,它可以接受一个comparator参数,用于指定排序规则,sorte... 目录一、sorted 操作的基础原理二、自定义排序的实现方式1. Comparator 接口的 Lam

Java Web实现类似Excel表格锁定功能实战教程

《JavaWeb实现类似Excel表格锁定功能实战教程》本文将详细介绍通过创建特定div元素并利用CSS布局和JavaScript事件监听来实现类似Excel的锁定行和列效果的方法,感兴趣的朋友跟随... 目录1. 模拟Excel表格锁定功能2. 创建3个div元素实现表格锁定2.1 div元素布局设计2.

HTML5 中的<button>标签用法和特征

《HTML5中的<button>标签用法和特征》在HTML5中,button标签用于定义一个可点击的按钮,它是创建交互式网页的重要元素之一,本文将深入解析HTML5中的button标签,详细介绍其属... 目录引言<button> 标签的基本用法<button> 标签的属性typevaluedisabled