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 网络安全 网络基础…...
嵌入式和单片机有什么区别?
目录 (1)什么是嵌入式? (2)什么是单片机? (3)嵌入式和单片机的共同点 (4)嵌入式和单片机的区别 (1)什么是嵌入式? 关…...
JSON.stringify 和 JSON.parse
JSON.stringify 是一个将 JavaScript 对象转换为 JSON 字符串的方法,它有三个参数: JSON.stringify(value, replacer, space) 参数详解 value (必需): 这是你想要转换为 JSON 字符串的 JavaScript 对象或数组。例如:…...
APP架构设计_2.用MVVM架构实现一个具体业务
2.MVVM架构图 3.MVVM 实现一个具体业务 3.1 界面层的实现 界面层实现时,需要遵循以下几点。 1)选择实现界面的元素 界面元素可以用 view 或 compose 来实现,这里用 view 实现。 2)提供一个状态容器 这里使用 ViewModel 作为状态容…...
安恒信息总裁宋端智,辞职了!活捉一枚新鲜出炉的餐饮人!
吉祥知识星球http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247485367&idx1&sn837891059c360ad60db7e9ac980a3321&chksmc0e47eebf793f7fdb8fcd7eed8ce29160cf79ba303b59858ba3a6660c6dac536774afb2a6330#rd 《网安面试指南》http://mp.weixin.qq.com/s?…...
《javaEE篇》--定时器
定时器概念 当我们不需要某个线程立刻执行,而是在指定时间点或指定时间段之后执行,假如我们要定期清理数据库里的一些信息时,如果每次都手动清理的话就太麻烦,所以就可以使用定时器。定时器就可以比作一个闹钟,可以让…...
OpenLayers3, 缩放、平移、复位操作
文章目录 一、前言二、代码示例 一、前言 本文基于OpenLayers3实现地图缩放、平移和复位操作 二、代码示例 <!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><htm…...
进程与线程(7)
IPC通信方式: 一、共享内存 system v : 共享内存 是一块,内核预留的空间 最高效的通信方式 (避免了用户空间 到 内核空间的数据拷贝) 二、IPC对象操作通用框架: key值 > 申请 》读写 》关闭 》卸载 1.ftok函数:…...
传知代码-自动化细胞核分割与特征分析(论文复现)
代码以及视频讲解 本文所涉及所有资源均在传知代码平台可获取 引言 细胞核分割和分类在医学研究和临床诊断中具有重要意义。精准的细胞核分割能够帮助医生更好地识别和分析细胞核的形态学特征,从而辅助疾病诊断、癌症检测以及药物研发。HoverNet是一种基于深度学…...
Vue UI - 可视化的Vue项目管理器
概述 Vue CLI 3.0 更新后,提供了一套全新的可视化Vue项目管理器 —— Vue UI。所以要想使用它,你的 Vue CL I版本必须要在v3.0以上。 一、启动Vue UI 1.1 环境准备 1.1.1 安装node.js 访问官网(外网下载速度较慢)或 http://nod…...
团队管理之敏捷开发
一、敏捷实践 敏捷开发中一直秉承的理念和宣言是:我们正在通过亲身实践以及帮助他人实践,揭示更好的软件开发方法。通过这项工作,我们认为:个体和交互胜过过程和工具、可以工作的软件胜过面面俱到的文档、客户合作胜过合同谈判、…...
东营网站备案代理公司/北京高端网站建设
文章目录rabbitmq 从入门到精通消息队列介绍1.1 介绍1.2 MQ解决什么问题应用解耦流量消峰消息分发异步消息1.3 常见消息队列及比较Rabbitmq安装2.1 服务端原生安装2.2 服务端Docker安装2.3 客户端安装2.4 设置用户和密码基于Queue实现生产者消费者模型基本使用(生产…...
网站建设申报书/中文域名查询官网
292. Nim 游戏 - 力扣(LeetCode) 剩下4块的时候,如果轮到你,那么你必输。 先简单推一下,如果第n块的时候轮到你: n 5 : 必胜(拿1块) n 6 : 必胜(拿2块) n…...
手机网站重要性/网站优化资源
小红书类种草文标题的写法分享 请看下图:...
精神文明建设委员会网站/关键词排名查询工具
state 和 props 主要的区别: 在于 props 是不可变的,而 state 可以根据与用户交互来改变。 组件需要定义 state 来更新和修改数据,子组件只能通过 props 来传递数据。 1.如何在组件中使用 props: <body> <div id&quo…...
阐述商业网站开发岗位需求分析/百度学术搜索
Android系统构架PAGE 1目 录TOC \o "1-3" \h \z \u 一、Android系统构架 1二、Linux内核层 2三、系统运行库层 3(一)系统库 3(二)Android运行时 4Android系统构架本次课程我们主要介绍Android的系统构架以及Linux内核层和系统运行库层的主要作用。一、Android系统构架…...
怎样做淘宝联盟网站/google首页
在后面标注字段类型就可以了 #{id,jdbcTypeVARCHAR}...