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

【Android】setText调用导致的悬浮窗抖动问题

在Android13中,有这么一个bug,写一个可以拖到的悬浮窗,这个悬浮窗里有TextView,在拖到某个位置后,再调用TextView的setText方法,会发现出现了一个窗口动画,悬浮窗跳到了起始位置,从开始的位置又滑动到当前位置,看起来就是出现了一个跳动。

试验例子

package com.example.testfloatview;import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;public class FloatWindowService extends Service {private WindowManager windowManager;private View floatView;private TextView textView;// 记录手指按下时的初始位置private int initialX, initialY;// 记录悬浮窗的初始位置private int initialWindowX, initialWindowY;@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {super.onCreate();// 初始化 WindowManagerwindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);// 加载布局文件LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);floatView = inflater.inflate(R.layout.float_window_layout, null);// 获取TextView控件textView = floatView.findViewById(R.id.text_view);// 设置初始文本textView.setText("hello, this is a test");// 创建 WindowManager.LayoutParamsWindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,WindowManager.LayoutParams.WRAP_CONTENT,Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY :WindowManager.LayoutParams.TYPE_PHONE,WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,PixelFormat.TRANSLUCENT);// 设置悬浮窗位置params.gravity = Gravity.TOP | Gravity.START;params.x = 0;params.y = 100;params.windowAnimations = 0;// 添加悬浮窗到窗口管理器windowManager.addView(floatView, params);// 设置触摸事件监听器floatView.setOnTouchListener(new View.OnTouchListener() {private int initialTouchX, initialTouchY;@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:// 记录初始位置initialX = params.x;initialY = params.y;initialTouchX = (int) event.getRawX();initialTouchY = (int) event.getRawY();break;case MotionEvent.ACTION_MOVE:// 计算新的位置params.x = initialX + (int) (event.getRawX() - initialTouchX);params.y = initialY + (int) (event.getRawY() - initialTouchY);// 更新悬浮窗位置windowManager.updateViewLayout(floatView, params);break;case MotionEvent.ACTION_UP:floatView.invalidate();textView.setText("hello");//       textView.setText("hello, this is a test");break;default:break;}return true; // 消费触摸事件}});// 使用Handler延迟5秒后更新文本new Handler().postDelayed(() -> {//     textView.setText("hello world");//     textView.setText("hello, this is a tttt");textView.setText("hello");}, 5000);}@Overridepublic void onDestroy() {super.onDestroy();// 移除悬浮窗if (floatView != null && windowManager != null) {windowManager.removeView(floatView);}}
}

package com.example.testfloatview;import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.view.View;
import android.widget.Toast;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {// 检查是否已经有悬浮窗权限if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {if (!Settings.canDrawOverlays(MainActivity.this)) {// 如果没有权限,跳转到系统设置页面申请权限Toast.makeText(MainActivity.this, "需要悬浮窗权限!", Toast.LENGTH_SHORT).show();Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,Uri.parse("package:" + getPackageName()));startActivityForResult(intent, 1);} else {// 已经有权限,启动悬浮窗服务startService(new Intent(MainActivity.this, FloatWindowService.class));finish(); // 关闭主Activity}} else {// 启动悬浮窗服务(低版本设备不需要权限)startService(new Intent(MainActivity.this, FloatWindowService.class));finish(); // 关闭主Activity}}});}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (requestCode == 1) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {if (Settings.canDrawOverlays(this)) {// 用户授予了权限,启动悬浮窗服务startService(new Intent(this, FloatWindowService.class));finish(); // 关闭主Activity} else {Toast.makeText(this, "未获得悬浮窗权限!", Toast.LENGTH_SHORT).show();}}}}
}

在开发者选项里,关闭掉 窗口动画缩放,就没有这个跳动问题了,所以这应该是窗口动画的bug,在调用setText的过程中,view的测量,布局中触发了窗口动画,并且使用了最初的坐标,大致是这样的思路。

相关文章:

【Android】setText调用导致的悬浮窗抖动问题

在Android13中,有这么一个bug,写一个可以拖到的悬浮窗,这个悬浮窗里有TextView,在拖到某个位置后,再调用TextView的setText方法,会发现出现了一个窗口动画,悬浮窗跳到了起始位置,从开…...

【从零开始学习计算机科学】数字逻辑(四)数字系统设计

【从零开始学习计算机科学】数字逻辑(四)数字系统设计 数字系统设计硬件描述语言 HDL(Hardware Description Language)Verilog HDL 的起源与发展HDL 软核、固核和硬核的重用HDL 的应用数字系统设计实现数字系统设计 一个数字集成电路的可以从不同的层次(系统级、算法级、…...

QT 作业 C++ day5

作业 代码 MyQThread.h class MyThread : public QThread {Q_OBJECT public:MyThread(QObject *parent nullptr); protected:void run() override; signals://向ui界面发送的 "复制进度" 的信号void copy_process_signal(int index); public slots:// "复…...

洛谷 P2234:[HNOI2002] 营业额统计 ← STL set

【题目来源】 https://www.luogu.com.cn/problem/P2234 【题目描述】 Tiger 最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger 拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析…...

植物神经功能紊乱检查不出来,浑身难受?

植物神经功能紊乱,又称为自主神经功能失调,是一种功能性神经症,它涉及身体多个系统的不规则反应,通常没有器质性病变作为基础。这意味着,尽管患者可能会体验到多种症状,如焦虑、紧张、心悸、疲劳、失眠等&a…...

vue3 遇到babel问题(exports is not defined) 解决方案

由于我在引用ant-design-vue插件,于是产生了下图的问题。 1.问题分析 Babel 是一个 JavaScript 编译器,主要用于:将 ES6 代码转译为 ES5 代码,以兼容旧版浏览器。处理模块化语法(如 import/export)。 2.解…...

基于SpringBoot+Vue的工商局商家管理系统

开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…...

ESP8266 入门(第 2 部分):使用 AT 命令

使用 AT 命令对 WiFi 收发器ESP8266编程 本教程是上一个教程 ESP8266 入门(第 1 部分)的延续。因此,简单回顾一下,在之前的教程中,我们介绍了 ESP 模块,并学习了一些基础知识。我们还使用 FTDI 串行适配器模块制作了一个开发板,该模块可以很容易地用于使用 AT 命令和 A…...

【CSS3】筑基篇

目录 复合选择器后代选择器子选择器并集选择器交集选择器伪类选择器 CSS 三大特性继承性层叠性优先级 背景属性背景色背景图背景图平铺方式背景图位置背景图缩放背景图固定背景复合属性 显示模式显示模式块级元素行内元素行内块元素 转换显示模式 结构伪类选择器结构伪类选择器…...

11-Agent中配置自己的插件

目录 关键词 摘要 速览 配置和集成自定义插件 使用AI插件在直播间绘制图像 API接口调用及配置说明 创建和配置API工具以生成图像 编写和配置参数及API调用说明 如何配置和使用API进行HTTP请求 配置和测试API插件的步骤 思维导图 发言总结 要点回顾 如何配置一个专…...

2025-03-08 学习记录--C/C++-PTA 习题10-1 判断满足条件的三位数

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、题目描述 ⭐️ 裁判测试程序样例&#xff1a; #include <stdio.h> #include <math.h>int search( int n );int…...

INFINI Labs 产品更新 | Easysearch 增加异步搜索等新特性

INFINI Labs 产品更新发布&#xff01;此次更新&#xff0c;Easysearch 增加了新的功能和数据类型&#xff0c;包括 wildcard 数据类型、Point in time 搜索 API、异步搜索 API、数值和日期字段的 doc-values 搜索支持&#xff0c;Console 新增了日志查询功能。 INFINI Easyse…...

关于网络数通工程师 OSPF 协议的常见面试问题

基础理论部分‌ ‌OSPF是什么&#xff1f;其核心设计目标及主要特性有哪些&#xff1f;‌ OSPF&#xff08;开放式最短路径优先&#xff09;是基于链路状态的内部网关协议&#xff08;IGP&#xff09;&#xff0c;使用Dijkstra的SPF算法计算最短路径树&#xff0c;核心目标包括…...

Go 语言 + libbpfgo 实战 eBPF 开发

Go 语言 libbpfgo 实战 eBPF 开发 1. 引言 这是专栏的第一篇文章&#xff0c;我们将从环境准备、示例代码运行和详解三个方面&#xff0c;带你快速入门 eBPF 开发。 &#x1f4cc; 读完这篇文章&#xff0c;你将学会&#xff1a; ✔️ 如何用 Go libbpfgo 开发 eBPF 程序。…...

练习题:74

目录 Python题目 题目 题目分析 需求理解 关键知识点 实现思路分析 复杂度分析 可能遇到的问题及注意事项 代码实现 代码解释 运行思路 1. 列表定义阶段 2. for 循环启动阶段 3. 偶数判断与 continue 语句执行阶段 4. 奇数元素输出阶段 5. 循环结束阶段 结束语…...

Python 性能优化:从入门到精通的实用指南

Langchain系列文章目录 01-玩转LangChain&#xff1a;从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块&#xff1a;四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain&#xff1a;从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…...

C# OPC DA获取DCS数据(提前配置DCOM)

OPC DA配置操作手册 配置完成后&#xff0c;访问远程ip&#xff0c;就能获取到服务 C#使用Interop.OPCAutomation采集OPC DA数据&#xff0c;支持订阅&#xff08;数据变化&#xff09;、单个读取、单个写入、断线重连...

xinference docker 部署方式

文章目录 简绍docker 安装方式访问地址对应官网在 dify 中 添加 xinference 容器内置大语言模型嵌入模型图像模型音频模型重排序模型视频模型 简绍 Xorbits Inference (Xinference) 是一个开源平台&#xff0c;用于简化各种 AI 模型的运行和集成。借助 Xinference&#xff0c;…...

基于Kubernetes部署MySQL主从集群

以下是一个基于Kubernetes部署MySQL主从集群的详细YAML示例&#xff0c;包含StatefulSet、Service、ConfigMap和Secret等关键配置。MySQL主从集群需要至少1个主节点和多个从节点&#xff0c;这里使用 StatefulSet 初始化脚本 实现主从自动配置。 1. 创建 Namespace (可选) ap…...

【Azure 架构师学习笔记】- Azure Databricks (17) --Delta Live Table和Delta Table

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (16) – Delta Lake 和 ADLS整合 前言 前面介绍了Delta Table&#xff0c;但是Databricks又推出了“Delta Live Tables&#xff08;DLTs&…...

Mybatis Generator 使用手册

第一章 什么是Mybatis Generator&#xff1f; MyBatis Generator Core – Introduction to MyBatis Generator MyBatis生成器&#xff08;MBG&#xff09;是MyBatis框架的代码生成工具。它支持为所有版本的MyBatis生成代码&#xff0c;通过解析数据库表&#xff08;或多个表&…...

快乐数 力扣202

一、题目 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。如果这个过程 结果为 1&…...

SPA单页面应用优化SEO

1.SSR服务端渲染 将组件或页面通过服务器生成html&#xff0c;再返回给浏览器&#xff0c;如nuxt.js或vue-server-renderer const Vue require(vue); const server require(express)(); const renderer require(vue-server-renderer).createRenderer();const vueApp new …...

城市霓虹灯夜景拍照后期Lr调色教程,手机滤镜PS+Lightroom预设下载!

调色教程 在城市霓虹灯夜景拍摄中&#xff0c;由于现场光线复杂等因素&#xff0c;照片可能无法完全呈现出当时的视觉感受。通过 Lr 调色&#xff0c;可以弥补拍摄时的不足。例如&#xff0c;运用基本调整面板中的曝光、对比度、阴影等工具&#xff0c;可以处理出画面的整体明暗…...

通领科技冲刺北交所

高质量增长奔赴产业新征程 日前&#xff0c;通领科技已正式启动在北交所的 IPO 进程&#xff0c;期望借助资本市场的力量&#xff0c;加速技术升级&#xff0c;推动全球化战略布局。这一举措不仅展现了中国汽车零部件企业的强大实力&#xff0c;也预示着行业转型升级的新突破。…...

隐私保护在 Facebook 用户身份验证中的应用

在这个数字化的时代&#xff0c;个人隐私保护成为了公众关注的焦点。社交媒体巨头 Facebook 作为全球最大的社交平台之一&#xff0c;拥有数十亿用户&#xff0c;其在用户身份验证过程中对隐私保护的重视程度直接影响着用户的安全感和信任度。本文将探讨 Facebook 在用户身份验…...

深度学习/强化学习调参技巧

深度调优策略 1. 学习率调整 技巧&#xff1a;学习率是最重要的超参数之一。过大可能导致训练不稳定&#xff0c;过小则收敛速度慢。可以使用学习率衰减&#xff08;Learning Rate Decay&#xff09;或自适应学习率方法&#xff08;如Adam、RMSprop&#xff09;来动态调整学习…...

python面试常见题目

1、python 有几种数据类型 数字:整形 &#xff08;int&#xff09;,浮点型 &#xff08;float&#xff09;布尔 &#xff08; bool&#xff09;:false true字符串 &#xff08;string&#xff09;列表 &#xff08;list&#xff09;元组 &#xff08;tuple&#xff09;字典 &…...

echarts折线图设置背景颜色:X轴和Y轴组成部分背景色

echarts折线图设置背景颜色 关键代码 splitArea: {show: true,areaStyle: {color: [#F2F2F2],},},完整代码位置显示 yAxis: {type: value,boundaryGap: [0, 100%],max: 1,interval: 1,// 于设置y轴的字体axisLabel: {show: false, //这里的show用于设置是否显示y轴下的字体 默…...

文本处理Bert面试内容整理-BERT的应用场景有哪些?

BERT(Bidirectional Encoder Representations from Transformers)在多个自然语言处理(NLP)任务中表现出了强大的能力。由于其能够捕捉双向上下文信息和强大的迁移学习能力,BERT广泛应用于各种NLP场景。以下是BERT的一些典型应用场景: 1. 文本分类 文本分类任务旨在将文本…...