Android 修改SystemUI 音量条的声音进度条样式
一、前言
Android System UI 开发经常会遇到修改音量进度条样式的需求,主要涉及的类有VolumeDialogImpl与xml文件,接下来会逐步实现流程。先看看效果。
修改前
修改后
二、找到对应类
通过aidegen 打断点调试对应代码类VolumeDialogImpl定位到volume_dialog就是对话框布局。mDialog.setContentView(R.layout.volume_dialog);
类路径:frameworks/base/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
private void initDialog() {mDialog = new CustomDialog(mContext);initDimens();mConfigurableTexts = new ConfigurableTexts(mContext);mHovering = false;mShowing = false;mWindow = mDialog.getWindow();mWindow.requestFeature(Window.FEATURE_NO_TITLE);mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);mWindow.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);mWindow.addPrivateFlags(WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY);mWindow.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);mWindow.setWindowAnimations(com.android.internal.R.style.Animation_Toast);WindowManager.LayoutParams lp = mWindow.getAttributes();lp.format = PixelFormat.TRANSLUCENT;lp.setTitle(VolumeDialogImpl.class.getSimpleName());lp.windowAnimations = -1;lp.gravity = mContext.getResources().getInteger(R.integer.volume_dialog_gravity);mWindow.setAttributes(lp);mWindow.setLayout(WRAP_CONTENT, WRAP_CONTENT);mDialog.setContentView(R.layout.volume_dialog);mDialogView = mDialog.findViewById(R.id.volume_dialog);mDialogView.setAlpha(0);mDialog.setCanceledOnTouchOutside(true);
三、音量条代码
@SuppressLint("InflateParams")private void initRow(final VolumeRow row, final int stream, int iconRes, int iconMuteRes,boolean important, boolean defaultStream) {row.stream = stream;row.iconRes = iconRes;row.iconMuteRes = iconMuteRes;row.important = important;row.defaultStream = defaultStream;row.view = mDialog.getLayoutInflater().inflate(R.layout.volume_dialog_row, null);row.view.setId(row.stream);row.view.setTag(row);row.header = row.view.findViewById(R.id.volume_row_header);row.header.setId(20 * row.stream);if (stream == STREAM_ACCESSIBILITY) {row.header.setFilters(new InputFilter[] {new InputFilter.LengthFilter(13)});}row.dndIcon = row.view.findViewById(R.id.dnd_icon);row.slider = row.view.findViewById(R.id.volume_row_slider);row.slider.setOnSeekBarChangeListener(new VolumeSeekBarChangeListener(row));row.number = row.view.findViewById(R.id.volume_number);row.anim = null;final LayerDrawable seekbarDrawable =(LayerDrawable) mContext.getDrawable(R.drawable.volume_row_seekbar);final LayerDrawable seekbarProgressDrawable = (LayerDrawable)((RoundedCornerProgressDrawable) seekbarDrawable.findDrawableByLayerId(android.R.id.progress)).getDrawable();row.sliderProgressSolid = seekbarProgressDrawable.findDrawableByLayerId(R.id.volume_seekbar_progress_solid);final Drawable sliderProgressIcon = seekbarProgressDrawable.findDrawableByLayerId(R.id.volume_seekbar_progress_icon);row.sliderProgressIcon = sliderProgressIcon != null ? (AlphaTintDrawableWrapper)((RotateDrawable) sliderProgressIcon).getDrawable() : null;row.slider.setProgressDrawable(seekbarDrawable);row.icon = row.view.findViewById(R.id.volume_row_icon);row.setIcon(iconRes, mContext.getTheme());if (row.icon != null) {if (row.stream != AudioSystem.STREAM_ACCESSIBILITY) {row.icon.setOnClickListener(v -> {Events.writeEvent(Events.EVENT_ICON_CLICK, row.stream, row.iconState);mController.setActiveStream(row.stream);if (row.stream == AudioManager.STREAM_RING) {final boolean hasVibrator = mController.hasVibrator();if (mState.ringerModeInternal == AudioManager.RINGER_MODE_NORMAL) {if (hasVibrator) {mController.setRingerMode(AudioManager.RINGER_MODE_VIBRATE, false);} else {final boolean wasZero = row.ss.level == 0;mController.setStreamVolume(stream,wasZero ? row.lastAudibleLevel : 0);}} else {mController.setRingerMode(AudioManager.RINGER_MODE_NORMAL, false);if (row.ss.level == 0) {mController.setStreamVolume(stream, 1);}}} else {final boolean vmute = row.ss.level == row.ss.levelMin;mController.setStreamVolume(stream,vmute ? row.lastAudibleLevel : row.ss.levelMin);}row.userAttempt = 0; // reset the grace period, slider updates immediately});} else {row.icon.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);}}}
四、音量条布局则位于volume_dialog_row.xml中
<!--Copyright (C) 2015 The Android Open Source ProjectLicensed under the Apache License, Version 2.0 (the "License");you may not use this file except in compliance with the License.You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, softwaredistributed under the License is distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.See the License for the specific language governing permissions andlimitations under the License.
-->
<FrameLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:tag="row"android:layout_height="wrap_content"android:layout_width="@dimen/volume_dialog_panel_width"android:clipChildren="false"android:clipToPadding="false"android:gravity="center"android:paddingTop="@dimen/volume_dialog_ringer_rows_padding"android:paddingBottom="@dimen/volume_dialog_ringer_rows_padding"android:background="@drawable/volume_row_rounded_background"android:theme="@style/volume_dialog_theme"><LinearLayoutandroid:layout_height="wrap_content"android:layout_width="@dimen/volume_dialog_panel_width"android:gravity="center"android:layout_gravity="center"android:orientation="vertical" ><TextViewandroid:id="@+id/volume_row_header"android:layout_width="wrap_content"android:layout_height="wrap_content"android:ellipsize="end"android:maxLength="10"android:maxLines="1"android:visibility="gone"android:textColor="?android:attr/colorControlNormal"android:textAppearance="@style/TextAppearance.Volume.Header" /><FrameLayoutandroid:id="@+id/volume_row_slider_frame"android:layout_width="match_parent"android:layout_height="@dimen/volume_row_slider_height"><SeekBarandroid:id="@+id/volume_row_slider"android:paddingLeft="0dp"android:paddingRight="0dp"android:paddingStart="0dp"android:paddingEnd="0dp"android:clickable="true"android:layout_width="@dimen/volume_row_slider_height"android:layout_height="match_parent"android:layout_gravity="center"android:thumb="@null"android:splitTrack="false"android:progressDrawable="@drawable/volume_row_seekbar"android:background="@null"android:layoutDirection="ltr"android:rotation="270" /><include layout="@layout/volume_dnd_icon"/></FrameLayout><com.android.keyguard.AlphaOptimizedImageButtonandroid:visibility="gone"android:id="@+id/volume_row_icon"style="@style/VolumeButtons"android:layout_width="@dimen/volume_dialog_tap_target_size"android:layout_height="@dimen/volume_dialog_tap_target_size"android:background="@drawable/ripple_drawable_20dp"android:layout_marginBottom="@dimen/volume_dialog_row_margin_bottom"android:tint="@color/accent_tint_color_selector"android:soundEffectsEnabled="false" /></LinearLayout></FrameLayout>
对SeekBar音量条进行修改增加样式
android:thumb="@drawable/ic_launcher_round"
android:progressDrawable="@drawable/volume_row_seekbar"
其中icon progress 就是一张ic_launcher_round图片
而volume_row_seekbar.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"><item android:id="@android:id/background"android:gravity="center_vertical|fill_horizontal"><shape android:shape="rectangle"><size android:height="@dimen/seek_bar_height" /><solid android:color="#eeeeee" /><corners android:radius="@dimen/seek_bar_corner_radius" /></shape></item><item android:id="@android:id/progress"android:gravity="center_vertical|fill_horizontal"><scale android:scaleWidth="100%"><shape android:shape="rectangle"><size android:height="@dimen/seek_bar_height" /><solid android:color="#0091ff" /><corners android:radius="@dimen/seek_bar_corner_radius" /></shape></scale></item>
</layer-list>
五、待续
相关文章:

Android 修改SystemUI 音量条的声音进度条样式
一、前言 Android System UI 开发经常会遇到修改音量进度条样式的需求,主要涉及的类有VolumeDialogImpl与xml文件,接下来会逐步实现流程。先看看效果。 修改前 修改后 二、找到对应类 通过aidegen 打断点调试对应代码类VolumeDialogImpl定位到volume_d…...
电商场景的视频生成的prompt测评集合
1.收集的一些提示词 一台写着Vidu的赛车在路上飞驰,赛车上面坐着一只乌龟 一个宇航员在太空中骑单车 两个巨大的机器人在打架,电影风格,史诗感,高细节 在科幻电影风格中,两个巨大的机器人在城市废墟中激烈战斗。使用高角度俯拍,展现机器人的宏伟和战斗的史诗感。机器人…...

day34
1 非阻塞型IO 让我们的read函数不再阻塞,无论是否读取到消息,立刻返回 1.1 fcntl函数 原型:int fcntl(int fd, int cmd, ... /* arg */ ); 调用:int flag fcntl(描述符,F_GETFL) fcntl(描述符,F_SETFL&am…...

无缝融入,即刻智能[三]:Dify-LLM平台知识库构建(多路召回、精排重排),43K+星标见证专属智能方案
无缝融入,即刻智能[三]:Dify-LLM平台知识库构建(多路召回、精排重排),43K+星标见证专属智能方案 大语言模型的训练数据一般基于公开的数据,且每一次训练需要消耗大量算力,这意味着模型的知识一般不会包含私有领域的知识,同时在公开知识领域存在一定的滞后性。为了解决这一…...
AWS服务WAF
在 AWS 中使用 Web Application Firewall (WAF) 来防御常见的攻击手段,如 DDoS 攻击和 SQL 注入攻击,可以通过创建和配置规则来实现。下面是如何使用 AWS WAF 阻止这些常见攻击的详细操作步骤。 1. 登录到 AWS 管理控制台 打开 AWS 管理控制台。使用你…...

二叉树中的奇偶树问题
目录 一题目: 二思路汇总: 1.二叉树层序遍历: 1.1题目介绍: 1.2 解答代码(c版): 1.3 解答代码(c版): 1.4 小结一下: 2.奇偶树分析…...

GD - EmbeddedBuilder - 用DMA进行串口发送接收,支持接收不定长包
文章目录 GD - EmbeddedBuilder - 用DMA进行串口发送接收,支持接收不定长包概述笔记硬件连接图形化配置485EN的配置串口的图形化配置 代码实现main.cgd32f3x0_hal_it.cgd32f3x0_hal_init.cgd32f3x0_hal_init.hgd32f3x0_hal_it.hgd32f3x0_libopt.h 备注END GD - Embe…...
英语中apartment(公寓)(美式)、house(房子)、flat(公寓)(英式)、villa(别墅)、room(房间)区别
文章目录 英语中apartment、house、flat、villa、room区别 英语中apartment、house、flat、villa、room区别 在英语中,“apartment”、“house”、“flat”、“villa”、和 “room” 这些词语都与居住空间有关,但它们各自的含义和用途有所不同ÿ…...

黑马头条vue2.0项目实战(十一)——功能优化(组件缓存、响应拦截器、路由跳转与权限管理)
1. 组件缓存 1.1 介绍 先来看一个问题? 从首页切换到我的,再从我的回到首页,我们发现首页重新渲染原来的状态没有了。 首先,这是正常的状态,并非问题,路由在切换的时候会销毁切出去的页面组件ÿ…...
《AI视频类工具之一—— 即创》
一.简介 官网:即创 - 一站式智能创意生产与管理平台 即创是字节跳动(现更名为抖音集团)旗下的一款一站式智能创意生产与管理平台,旨在帮助用户高效地进行创意内容的生成、管理和分析。 二.功能介绍 视频创作: 智能成片:利用AI技术自动编辑视频片段,快速生成完整的视频…...
CSS的:host伪类:精确定位于Web组件的指南
随着Web组件技术的发展,自定义元素(Custom Elements)已经成为现代Web开发中不可或缺的一部分。CSS的:host伪类为Web组件的样式封装提供了一种强大的工具,它允许开发者为自定义Web组件的宿主元素定义样式。本文将详细介绍:host伪类…...

安卓sdk manager下载安装
安卓sdk下载安装 android SDK manager下载 环境变量配置 ANDROID_HOME:D:\Android %ANDROID_HOME%\tools %ANDROID_HOME%\platform-tools %ANDROID_HOME%\build-tools\29.0.3Android SDK Platform-tools公用开发工具包,需要下载 Android SDK Tools基础…...
CV学习笔记3-图像特征提取
图像特征提取是计算机视觉中的一个关键步骤,其目标是从图像中提取有意义的特征,以便进行进一步的分析或任务,如分类、检测、分割等。特征提取可以帮助减少数据的维度,同时保留重要的信息。以下是常见的图像特征提取方法和技术&…...

Git使用方法(三)---简洁版上传git代码
1 默认已经装了sshWindows下安装SSH详细介绍-CSDN博客 2 配置链接github的SSH秘钥 1 我的.ssh路径 2 进入路径cd .ssh 文件 3 生成密钥对 ssh-keygen -t rsa -b 4096 (-t 秘钥类型 -b 生成大小) 输入完会出现 Enter file in which to save the key (/c/Users/Administrator/…...

8.21-部署eleme项目
1.设置主从从mysql57服务器 (1)配置主数据库 [rootmsater_5 ~]# systemctl stop firewalld[rootmsater_5 ~]# setenforce 0[rootmsater_5 ~]# systemctl disable firewalldRemoved symlink /etc/systemd/system/multi-user.target.wants/firewalld.serv…...

多目标跟踪之ByteTrack论文(翻译+精读)
ByteTrack:通过关联每个检测框进行多对象跟踪 摘要 翻译 多对象跟踪(MOT)旨在估计视频中对象的边界框和身份。大多数方法通过关联分数高于阈值的检测框来获取身份。检测分数低的物体,例如被遮挡的物体被简单地丢弃,…...
【实践】Java开发常用工具类或中间件
在Java开发中,有许多常用的工具类和中间件,它们可以显著提高开发效率,简化代码,并提供强大的功能。这些工具类和中间件广泛应用于各种类型的Java应用程序中,包括Web应用、企业级应用、微服务等。以下是一些在Java开发中…...

Vue2移动端(H5项目)项目封装车牌选择组件
一、最终效果 二、参数配置 1、代码示例: <t-keyword:isShow"isShow"ok"isShowfalse"cancel"isShowfalse"inputchange"inputchange":finalValue"trailerNo"/>2、配置参数(TKeyword Attribute…...

四川财谷通信息技术有限公司抖音小店的优势
在数字化浪潮的推动下,电商行业迎来了前所未有的发展机遇,而抖音小店作为新兴的电商平台,凭借其独特的社交属性和便捷的购物体验,迅速赢得了广大消费者的青睐。在众多抖音小店中,四川财谷通信息技术有限公司旗下的抖音…...
2025届八股文:计算机网络高频重点面试题
鉴于排版复杂且篇幅过长,本文仅列举出问题,而未给出答案,有需要答案的同学可后台私信。整理总结不易,请尊重劳动成果,转载请注明出处。 目录 网络基础 HTTP TCP UDP IP PING WebSocket DNS 网络安全 网络基础…...

wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...

python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...

LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...

算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...

Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...