完整教程:Android 自定义电池组件(BatteryView)

news/2025/9/22 16:05:36/文章来源:https://www.cnblogs.com/tlnshuju/p/19105454

完整教程:Android 自定义电池组件(BatteryView)

2025-09-22 16:03  tlnshuju  阅读(0)  评论(0)    收藏  举报

支持:

  • XML 与代码动态设置电量(0–100)

  • 充电 charging 与快充 fastCharging 区分(闪电样式 + 动画)

  • 电量阈值自动配色:<20% 红、<50% 橙、≥50% 绿

  • 可配置边框/轨道/电量/闪电颜色;可显示百分比文本

  • 支持无障碍(contentDescription、AccessibilityLiveRegion)

  • 支持状态保存(旋转/进程重建)

  • 平滑动画过渡(setLevelAnimated)

1、自定义属性 res/values/attrs.xml

术语说明:

  • borderColor:电池外框线条颜色。

  • trackColor:电池内部“轨道/背景”颜色(未被电量填充区域)。

  • fillColor:电量填充的基础颜色(当未启用分段阈值或外部强制指定时)。

2、 组件代码 BatteryView.kt

package com.yourpkg.widget
val y6 = t + h * 0.35f
boltPath.reset()
boltPath.moveTo(x1, y1)
boltPath.lineTo(x2, y2)
boltPath.lineTo(x3, y3)
boltPath.lineTo(x4, y4)
boltPath.lineTo(x5, y5)
boltPath.lineTo(x6, y6)
boltPath.close()
}
// endregion
// region — Accessibility
private fun updateContentDesc() {
val charge = when {
fastCharging -> "(快充中)"
charging -> "(充电中)"
else -> ""
}
contentDescription = "电量 $level%$charge"
}
// endregion
// region — State
override fun onSaveInstanceState(): Parcelable? {
val superState = super.onSaveInstanceState()
return SavedState(superState).also {
it.level = level
it.charging = charging
it.fastCharging = fastCharging
it.showPercentage = showPercentage
it.chargePulse = chargePulse
}
}
override fun onRestoreInstanceState(state: Parcelable?) {
val ss = state as? SavedState
super.onRestoreInstanceState(ss?.superState ?: state)
ss?.let {
level = it.level
charging = it.charging
fastCharging = it.fastCharging
showPercentage = it.showPercentage
chargePulse = it.chargePulse
toggleChargeAnim(charging)
}
}
private class SavedState : BaseSavedState {
var level: Int = 0
var charging: Boolean = false
var fastCharging: Boolean = false
var showPercentage: Boolean = false
var chargePulse: Float = 0f
constructor(superState: Parcelable?) : super(superState)
private constructor(inParcel: Parcel) : super(inParcel) {
level = inParcel.readInt()
charging = inParcel.readInt() == 1
fastCharging = inParcel.readInt() == 1
showPercentage = inParcel.readInt() == 1
chargePulse = inParcel.readFloat()
}
override fun writeToParcel(out: Parcel, flags: Int) {
super.writeToParcel(out, flags)
out.writeInt(level)
out.writeInt(if (charging) 1 else 0)
out.writeInt(if (fastCharging) 1 else 0)
out.writeInt(if (showPercentage) 1 else 0)
out.writeFloat(chargePulse)
}
companion object {
@JvmField val CREATOR: Parcelable.Creator = object : Parcelable.Creator {
override fun createFromParcel(source: Parcel): SavedState = SavedState(source)
override fun newArray(size: Int): Array = arrayOfNulls(size)
}
}
}
// endregion
// region — Utils
private fun dp(v: Float) = v * resources.displayMetrics.density
private fun sp(v: Float) = v * resources.displayMetrics.scaledDensity
// endregion
}

3、XML 用法示例

4、代码控制示例

val bv = findViewById(R.id.battery)
// 动态设置电量
bv.level = 18 // 立即刷新
bv.setLevelAnimated(76) // 平滑动画到 76%
// 充电状态
bv.charging = true // 显示闪电 + 呼吸动画
bv.fastCharging = true // 闪电更大、视觉更强
// 开关百分比
bv.showPercentage = false
// 结合业务:阈值配色自动处理(<20 红、<50 橙、≥50 绿),无需额外代码

5、常见问题(结合你之前的疑问)

  • Q: borderColor 和 trackColor 是什么?
    A: borderColor 是外框线条;trackColor 是内部未充满的背景。

  • Q: 无障碍报错 isImportantForAccessibility
    A: 组件内已设置:

    importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_YES

    accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_POLITE

    同时动态更新 contentDescription,读屏会播报“电量 76%,快充中”。

  • Q: 如何自定义颜色?
    在 XML 传入 bv_lowColor/bv_mediumColor/bv_highColor,或在代码里直接修改。

  • Q: 性能如何?
    组件绘制简单,动画为轻量级呼吸,postOnAnimation 驱动,开销极低。

6、小扩展(可选)

  • 电量渐变色:将 fillPaint 设置为 LinearGradient,根据 level 动态改变 endX。

  • 低电量闪烁:level<10 且非充电时,使用 alpha 在 120–255 之间脉动。

  • RTL 适配:当 layoutDirection == LAYOUT_DIRECTION_RTL 时从右向左填充(可根据需要调整 fillRect 计算)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/909576.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安阳信息港网站wordpress翻译配置

在之前的博客中&#xff0c;我们使用Thymeleaf&#xff0c;Bower和Bootstrap构建了登录页面&#xff0c;并将其部署到了Heroku。 在此博客中&#xff0c;我们将介绍用于前端的AngularJS和在后端的Spring Boot Web服务的一些功能。 我们将从“登录/注销”部分开始。 让我们开始…

关于音乐的个人网站搜索排名优化公司

目录 第一章 引言 第二章 数据准备 第三章 贝叶斯路径规划模型训练 第四章 路径规划预测 第五章 路径执行 第六章 实验结果分析 第一章 引言 自动驾驶技术的发展带来了自动驾驶车辆的出现&#xff0c;而路径规划作为自动驾驶车辆的关键功能之一&#xff0c;对于确定最佳行…

网站关键词设置多少个深圳建筑公司排名前二十

视频生成模型&#xff0c;如 Stable Video Diffusion 和 Videocrafter&#xff0c;已经能够生成合理且高分辨率的视频。但这些技术进步也带来了被恶意利用的风险&#xff0c;比如用于制造假新闻或进行政治宣传。因此&#xff0c;来自弗吉尼亚大学和亥姆霍兹信息安全中心&#x…

网站 建设方案合肥市建设建筑网站

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/131901444 红胖子(红模仿)的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软…

摄影作品展示网站flash全站源码长沙app开发公司排名

目录 引言 1 导入数据集 2 清洗数据集 3 确定允许的最大序列长度 4 选择合理的文本和摘要 5 对文本进行标记 6 删除空文本和摘要 7 构建模型 7.1 编码器 7.2 解码器 8 训练模型 9 测试模型 10 注意 11 整体代码 引言 文本摘要是指在捕捉其本质的同时缩短长文本的…

中文乱码速查表

从小红书贴过来的,自己保存看。侵删。为了自己能看到乱码快快解决。

使用PySide6/PyQt6实现全国省市区的级联选择组件

使用PySide6/PyQt6实现全国省市区的级联选择组件在基于BS或者H5实现全国省市区的级联选择组件,相对比较容易,一般都要有现成的封装,如对于移动端H5或者小程序的Vant4界面库,他们直接安装使用内置的数据即可进行调用…

WPF TextBlock effect DropShadrowEffect,BlurEffect

<Window x:Class="WpfApp32.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d=&quo…

重庆建设集团网站企业建设流程

目录 一、动态顺序表结构定义 二、动态顺序表初始化 三、动态顺序表打印 四、动态顺序表尾插 五、封装扩容函数 六、动态顺序表头插 七、动态顺序表的尾删 八、动态顺序表的头删 九、动态顺序表任意位置插入 十、动态顺序表任意位置删除 十一、动态顺序表销毁 十二、…

求网站建设贵阳电商网站建设

一:论语 这个有意思,我们可以从中得出的是&#xff0c;一个人过错 其实是潜意思决定的 行为见品质 但知错更改也是nice的 二:题目 三:上码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* Tr…

服务周到的微网站建设wordpress地理定位

精简jdk包帖子“ 紧凑数字格式出现在JDK 12中 ”演示了对JDK 12中 NumberFormat的支持&#xff0c;以支持紧凑数字格式 。 该帖子中显示的示例仅使用NumberFormat的实例&#xff0c;这些实例是通过调用NumberFormat的新重载getCompactNumberInstance(-)方法返回的&#xff0c;因…

做网站广告公司国外销售网站怎样建设

1.使用 typeof bar “object” 判断 bar 是不是一个对象有神马潜在的弊端&#xff1f;如何避免这种弊端&#xff1f;使用 typeof 的弊端是显而易见的(这种弊端同使用 instanceof)&#xff1a;let obj {};let arr [];console.log(typeof obj object); //trueconsole.log(typ…

开发购物平台网站费用网站关键词被改

目录 一、规则 二、方法 1、seed 2、identifier 1&#xff09;选取一个身份号 2&#xff09;选取一定比例的身份号作为测试集 3&#xff09;身份号的选取&#xff1a; 3、利用scikit-learn&#xff1a; 1) 随机生成&#xff1a; 2&#xff09;注&#xff1a;分类 3&a…

控制面板网站宁波网站建设服务

背景&#xff1a; 微软和谷歌母公司Alphabet最新公布的季度财报均显示&#xff0c;由于企业客户在人工智能服务上的投入增加&#xff0c;其云计算业务实现了显著的收入增长。尽管Meta在将人工智能技术转化为收益方面稍显滞后&#xff0c;但它表示&#xff0c;其相关努力对提高…

中山做网站专业的公司如何做网站竞品分析

2020年全国研究生数学建模大赛开始啦&#xff01;各学院&#xff1a; 为在大学生中倡导学习统计、应用统计的良好氛围&#xff0c;适应大数据时代的高校统计和数据科学人才的培养要求&#xff0c;提高研究生的数据挖掘、数据分析、运用计算机处理数据的能力&#xff0c;加强创新…

建设网站的企业费用东莞网络公司哪家好

背景在使用富士施乐的一体机中(其他厂商的一体机 也类似)&#xff0c;很多人的网络环境是动态IP的&#xff0c;即打印的IP地址是不固定的&#xff0c;随着每次开机或关机会变化&#xff0c;从而经常有人反应打印机不能打印或者扫描了。。总体思路1. 检查当前的IP设置2. 把相应的…

程序员做的简单的网站企业做网站和宣传册的作用

在视频制作过程中&#xff0c;为视频添加引人注目的封面是吸引观众的关键。而当我们需要批量处理多个视频时&#xff0c;如何快速、准确地置入封面就显得尤为重要。本文将为您揭示这一高效技巧&#xff0c;让您在一分钟内学会批量置入视频封面&#xff0c;提升视频的吸引力与观…

.NET驾驭Word之力:结构化文档元素操作

在前几篇文章中,我们学习了Word对象模型的基础知识、文本操作与格式设置等内容。掌握了这些基础知识后,我们现在可以进一步深入到文档的结构化元素操作,包括段落与节的管理、表格的创建与操作以及图片的插入等。本文…

行稳、致远 | 技术驱动下的思考感悟

行稳: 做好当下,结果第一 读书和加入京东以来的这十几年,我感触最深的一个点就是要做好当下。我个人是一个思维比较跳脱,想法算是比较多的人。总是喜欢瞎折腾,喜欢想东想西。有时候有点 “这山望见那山高” 的意思…

在控制台执行这段代码可以列出所有::selection规则

// 在控制台执行这段代码可以列出所有::selection规则 Array.from(document.styleSheets).forEach(sheet => { try { Array.from(sheet.cssRules).forEach(rule => { if(rule.selectorText && rule.sele…