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 网络安全 网络基础…...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
