自定义 浮动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

相关文章

Go语言实现将中文转化为拼音功能

《Go语言实现将中文转化为拼音功能》这篇文章主要为大家详细介绍了Go语言中如何实现将中文转化为拼音功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 有这么一个需求:新用户入职 创建一系列账号比较麻烦,打算通过接口传入姓名进行初始化。想把姓名转化成拼音。因为有些账号即需要中文也需要英

基于WinForm+Halcon实现图像缩放与交互功能

《基于WinForm+Halcon实现图像缩放与交互功能》本文主要讲述在WinForm中结合Halcon实现图像缩放、平移及实时显示灰度值等交互功能,包括初始化窗口的不同方式,以及通过特定事件添加相应... 目录前言初始化窗口添加图像缩放功能添加图像平移功能添加实时显示灰度值功能示例代码总结最后前言本文将

SpringBoot项目启动后自动加载系统配置的多种实现方式

《SpringBoot项目启动后自动加载系统配置的多种实现方式》:本文主要介绍SpringBoot项目启动后自动加载系统配置的多种实现方式,并通过代码示例讲解的非常详细,对大家的学习或工作有一定的... 目录1. 使用 CommandLineRunner实现方式:2. 使用 ApplicationRunne

使用Python实现批量访问URL并解析XML响应功能

《使用Python实现批量访问URL并解析XML响应功能》在现代Web开发和数据抓取中,批量访问URL并解析响应内容是一个常见的需求,本文将详细介绍如何使用Python实现批量访问URL并解析XML响... 目录引言1. 背景与需求2. 工具方法实现2.1 单URL访问与解析代码实现代码说明2.2 示例调用

Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单

《Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单》:本文主要介绍Springboot的ThreadPoolTaskScheduler线... 目录ThreadPoolTaskScheduler线程池实现15分钟不操作自动取消订单概要1,创建订单后

最好用的WPF加载动画功能

《最好用的WPF加载动画功能》当开发应用程序时,提供良好的用户体验(UX)是至关重要的,加载动画作为一种有效的沟通工具,它不仅能告知用户系统正在工作,还能够通过视觉上的吸引力来增强整体用户体验,本文给... 目录前言需求分析高级用法综合案例总结最后前言当开发应用程序时,提供良好的用户体验(UX)是至关重要

python实现自动登录12306自动抢票功能

《python实现自动登录12306自动抢票功能》随着互联网技术的发展,越来越多的人选择通过网络平台购票,特别是在中国,12306作为官方火车票预订平台,承担了巨大的访问量,对于热门线路或者节假日出行... 目录一、遇到的问题?二、改进三、进阶–展望总结一、遇到的问题?1.url-正确的表头:就是首先ur

Spring使用@Retryable实现自动重试机制

《Spring使用@Retryable实现自动重试机制》在微服务架构中,服务之间的调用可能会因为一些暂时性的错误而失败,例如网络波动、数据库连接超时或第三方服务不可用等,在本文中,我们将介绍如何在Sp... 目录引言1. 什么是 @Retryable?2. 如何在 Spring 中使用 @Retryable

如何评价Ubuntu 24.04 LTS? Ubuntu 24.04 LTS新功能亮点和重要变化

《如何评价Ubuntu24.04LTS?Ubuntu24.04LTS新功能亮点和重要变化》Ubuntu24.04LTS即将发布,带来一系列提升用户体验的显著功能,本文深入探讨了该版本的亮... Ubuntu 24.04 LTS,代号 Noble NumBAT,正式发布下载!如果你在使用 Ubuntu 23.

TP-LINK/水星和hasivo交换机怎么选? 三款网管交换机系统功能对比

《TP-LINK/水星和hasivo交换机怎么选?三款网管交换机系统功能对比》今天选了三款都是”8+1″的2.5G网管交换机,分别是TP-LINK水星和hasivo交换机,该怎么选呢?这些交换机功... TP-LINK、水星和hasivo这三台交换机都是”8+1″的2.5G网管交换机,我手里的China编程has