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

可拖动、可靠边的 popupWindow 实现

0 背景

  开发要实现一个可以拖动的圆角小窗,要求松手时,哪边近些靠哪边。并且还规定了拖动范围。样式如下:
在这里插入图片描述

1 实现

首先把 PopupWindow 的布局文件 pop.xml 实现

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="88dp"android:layout_height="132dp"android:background="@drawable/radius_12"android:id="@+id/mini_popup"android:visibility="visible"><com.google.android.material.imageview.ShapeableImageViewandroid:id="@+id/iv_live_cover"android:layout_width="88dp"android:scaleType="fitXY"android:layout_height="132dp"android:background="@color/purple_200"app:shapeAppearanceOverlay="@style/MiniDialogRoundedImageStyle" /><ImageViewandroid:id="@+id/iv_close"android:layout_width="16dp"android:layout_height="16dp"android:layout_alignParentRight="true"android:layout_marginTop="4dp"android:layout_marginRight="4dp"android:src="@color/teal_200" />
</RelativeLayout>

布局中圆角和 PopupWindow 的动画 style.xml

    <!-- 圆角图片 --><style name="MiniDialogRoundedImageStyle"><item name="cornerFamily">rounded</item><item name="cornerSize">12dp</item></style><!-- PopupWindow 的动画效果 --><style name="PopupWindowAnimation"><item name="android:windowEnterAnimation">@anim/live_popup_window_in_anim</item></style>

radius_12.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"><corners android:radius="12dp"/><solid android:color="@color/white"/>
</shape>

MyPopupWindow.java

package com.example.myapplication.popupwindow;import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.PopupWindow;import com.bumptech.glide.Glide;
import com.example.myapplication.R;public class MyPopupWindow extends PopupWindow {private Context mContext;private View mRootView;// 背景private ImageView mBackground;// 关闭弹窗private ImageView mIvClose;// 弹窗的移动范围private int mMinX;private int mMinY;private int mMaxX;private int mMaxY;// 屏幕宽高private int mScreenWidth;public MyPopupWindow(Context context) {super(context);mContext = context;mRootView = View.inflate(mContext, R.layout.pop, null);mScreenWidth = getScreenWidth(mContext);mMinX = dp2px(12);mMaxX = mScreenWidth - dp2px(12) - dp2px(88);mMinY = dp2px(12);mMaxY = dp2px(500);// 为了保证整体是圆角形状mRootView.findViewById(R.id.mini_popup).setClipToOutline(true);initView();}private void initView() {setContentView(mRootView);mBackground = mRootView.findViewById(R.id.iv_live_cover);mIvClose = mRootView.findViewById(R.id.iv_close);mIvClose.setOnClickListener(view -> this.dismiss());// 小窗的宽高setHeight(dp2px(132));setWidth(dp2px(88));this.setTouchInterceptor(new View.OnTouchListener() {int orgX, orgY;int offsetX, offsetY;@Overridepublic boolean onTouch(View view, MotionEvent motionEvent) {switch (motionEvent.getAction()) {case MotionEvent.ACTION_DOWN:orgX = (int) motionEvent.getX();orgY = (int) motionEvent.getY();break;case MotionEvent.ACTION_MOVE:offsetX = (int) motionEvent.getRawX() - orgX;offsetY = (int) motionEvent.getRawY() - orgY;// 限制 x 坐标offsetX = Math.max(offsetX, mMinX);offsetX = Math.min(offsetX, mMaxX);// 限制 y 坐标offsetY = Math.max(offsetY, mMinY);offsetY = Math.min(offsetY, mMaxY);update(offsetX, offsetY, -1, -1, true);break;case MotionEvent.ACTION_UP:// 小窗靠边if (offsetX < mScreenWidth / 2) {offsetX = mMinX;} else {offsetX = mMaxX;}update(offsetX, offsetY, -1, -1, true);break;}// 避免 view 中的其他点击事件被吞掉return false;}});// 设置小窗背景this.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.abc_vector_test));// 出现的动画this.setAnimationStyle(R.style.PopupWindowAnimation);}public void show(View anchor) {this.showAtLocation(anchor, Gravity.NO_GRAVITY, mMaxX, mMaxY);}@SuppressLint("CheckResult")public void setBackground(String url) {if (url != null && !TextUtils.isEmpty(url))Glide.with(mContext).load(url).into(mBackground);}public int dp2px(float dpValue) {return (int) (0.5f + dpValue * Resources.getSystem().getDisplayMetrics().density);}public int getScreenWidth(Context context) {DisplayMetrics localDisplayMetrics = new DisplayMetrics();((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(localDisplayMetrics);return localDisplayMetrics.widthPixels;}
}

最后在 MainActivity 中使用

mTextView = findViewById(R.id.myView);
if (mMyPopupWindow == null) {mMyPopupWindow = new MyPopupWindow(MainActivity.this);
}
mTextView.post(() -> {mMyPopupWindow.show(mTextView);
});

相关文章:

可拖动、可靠边的 popupWindow 实现

0 背景 开发要实现一个可以拖动的圆角小窗&#xff0c;要求松手时&#xff0c;哪边近些靠哪边。并且还规定了拖动范围。样式如下&#xff1a; 1 实现 首先把 PopupWindow 的布局文件 pop.xml 实现 <?xml version"1.0" encoding"utf-8"?> <R…...

C# 依赖注入如何实现

在 C# 中&#xff0c;依赖注入&#xff08;Dependency Injection&#xff0c;简称 DI&#xff09;是一种编程技术&#xff0c;用于减少代码之间的耦合。依赖注入可以通过构造函数注入、属性注入或方法注入实现。在 .NET Core 和 .NET 5 中&#xff0c;还提供了一个内置的依赖注…...

Redis 9 数据库

4 设置键的生存时间或过期时间 通过EXPIRE命令或者PEXPIRE命令&#xff0c;客户端可以以秒或者毫秒精度为数据库中的某个键设置生存时间&#xff08;TimeToLive&#xff0c;TTL&#xff09;&#xff0c;在经过指定的秒数或者毫秒数之后&#xff0c;服务器就会自动删除生存时间…...

43-设计问题-最小栈

原题链接&#xff1a; 198. 打家劫舍 题目描述&#xff1a; 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&a…...

基于RK3588全高端智能终端机器人主板

一、小尺寸板型设计 该款主板为小型板&#xff0c;尺寸仅为125*85mm&#xff0c;更小更紧凑&#xff0c;可完美适应各类高端智能自助终端&#xff1b; 二、八核高端处理器 采用RK3588S八核64位处理器&#xff0c;8nm LP制程&#xff0c;主频最高达2.4GHz&#xff0c;搭载Andr…...

穿越风波,“长红”的直播电商依然扎根产业和消费者

当消费者将最后一个快递拿进家门&#xff0c;2023年的双11也就落下了帷幕。相较于往年组队、拼单的玩法&#xff0c;如今最受欢迎的双11 流程&#xff0c;或许已经变成点进自己心仪主播、店铺的直播间&#xff0c;翻阅最新的产品清单&#xff0c;从中选择购物目标&#xff0c;在…...

LLM大模型 (chatgpt) 在搜索和推荐上的应用

目录 1 大模型在搜索的应用1.1 召回1.1.1 倒排索引1.1.2 倒排索引存在的问题1.1.3 大模型在搜索召回的应用 (实体倒排索引&#xff09; 1.2 排序1.2.1 大模型在搜索排序应用&#xff08;融入LLM实体排序&#xff09; 2 大模型在推荐的应用2.1 学术界关于大模型在推荐的研究2.2 …...

中国净初级生产力年度合成产品NPP(MYD17A3H.006)

中国净初级生产力年度合成产品NPP&#xff08;MYD17A3H.006&#xff09;由航天宏图实验室提供&#xff0c;根据NASA MODIS数据&#xff08;MYD17A3H.006&#xff09;通过航天宏图 Smoother计算得到的平滑后NPP产品&#xff0c;解决了影像云雾覆盖、像元异常值等问题。对处理后的…...

GitHub如何删除仓库

GitHub如何删除仓库 删除方法第一步第二步第三步 删除方法 第一步 在仓库的界面选择Settings 第二步 选择General,页面拉到最后。 第三步 删除仓库。...

漫谈广告机制设计 | 万剑归宗:聊聊广告机制设计与收入提升的秘密(3)

​书接上文漫谈广告机制设计 | 万剑归宗&#xff1a;聊聊广告机制设计与收入提升的秘密&#xff08;2&#xff09;&#xff0c;我们聊到囚徒困境是完全信息静态博弈&#xff0c;参与人存在占优策略&#xff0c;最终达到占优均衡&#xff0c;并且是对称占优均衡。接下来我们继续…...

安装系统时无raid驱动处理办法

场景描述 安装系统时可以进入安装界面&#xff0c;但是无法识别到硬盘&#xff0c;查看服务器硬件均无异常且从bios或者raid配置界面中能正常看到raid信息及硬盘信息&#xff0c;运行lspci 命令查看到服务器有raid卡&#xff0c;但是未加载驱动。 获取驱动程序模块 查看raid…...

ForkLift:macOS文件管理器/FTP客户端

ForkLift 是一款macOS下双窗口的文件管理器&#xff0c;可以代替本地的访达。ForkLift同时具备连接Ftp、SFtp、WebDav以及云服务器。 ForkLift还具备访达不具备的小功能&#xff0c;比如从文件夹位置打开终端&#xff0c;显示隐藏文件&#xff0c;制作替换等功能。ForkLift 是一…...

信息系统项目管理师 第四版 第20章 高级项目管理

1.项目集管理 1.1.项目集管理标准 1.2.项目集管理角色和职责 1.3.项目集管理绩效域 2.项目组合管理 2.1.项目组合管理标准 2.2.项目组合管理角色和职责 2.3.项目组合管理绩效域 3.组织级项目管理 3.1.组织级项目管理标准 3.2.业务价值与业务评估 3.3.OPM框架要素 3…...

Apache Pulsar 技术系列 - 基于 Pulsar 的海量 DB 数据采集和分拣

导语 Apache Pulsar 是一个多租户、高性能的服务间消息传输解决方案&#xff0c;支持多租户、低延时、读写分离、跨地域复制、快速扩容、灵活容错等特性。本文是 Pulsar 技术系列中的一篇&#xff0c;主要介绍 Pulsar 在海量DB Binlog 增量数据采集、分拣场景下的应用。 前言…...

HDFS、MapReduce原理--学习笔记

1.Hadoop框架 1.1框架与Hadoop架构简介 &#xff08;1&#xff09;广义解释 从广义上来说&#xff0c;随着大数据开发技术的快速发展与逐步成熟&#xff0c;在行业里&#xff0c;Hadoop可以泛指为&#xff1a;Hadoop生态圈。 也就是说&#xff0c;Hadoop指的是大数据生态圈整…...

PC端使子组件的弹框关闭

子组件 <template><el-dialog title"新增部门" :visible"showDialog" close"close"> </el-dialog> </template> <script> export default {props: {showDialog: {type: Boolean,default: false,},},data() {retu…...

PHPStorm PHP-CS-Fixer

我用的是brew安装&#xff1a; brew install php-cs-fixer phpstorm配置&#xff1a; setting搜索fixer 指定安装php-cs-fixer的目录&#xff1a; https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/doc/installation.rst 图文详解PHPStorm实现自动执行代码格式化-…...

SpringBoot中日志的使用log4j

SpringBoot中日志的使用log4j 项目中日志系统是必不可少的&#xff0c;目前比较流行的日志框架有 log4j、logback 等&#xff0c;这两个框架的作者是同一个 人&#xff0c;Logback 旨在作为流行的 log4j 项目的后续版本&#xff0c;从而恢复 log4j 离开的位置。 另外 slf4j(…...

迭代器与生成器

章节目录&#xff1a; 一、迭代器1.1 相关概述1.2 基本使用1.3 自定义迭代器 二、生成器2.1 相关概述2.2 基本使用2.3 三种应用场景 三、yield 和 class 定义的迭代器对比四、结束语 一、迭代器 1.1 相关概述 迭代是 Python 最强大的功能之一&#xff0c;是访问集合元素的一种…...

适用于 Windows 的 10 个最佳视频转换器:快速转换高清视频

您是否遇到过由于格式不兼容而无法在您的设备上播放视频或电影的情况&#xff1f;您想随意播放从您的相机、GoPro 导入的视频&#xff0c;还是以最合适的格式将它们上传到媒体网站&#xff1f;您的房间里是否有一堆 DVD 光盘&#xff0c;想将它们转换为数字格式以便于播放&…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...

掌握 HTTP 请求:理解 cURL GET 语法

cURL 是一个强大的命令行工具&#xff0c;用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中&#xff0c;cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...