Android自定义电池组件实例代码(BatteryView)
作者:消失的旧时光-1943
支持:
XML 与代码动态设置电量(0–100)
充电
charging
与快充fastCharging
区分(闪电样式 + 动画)电量阈值自动配色:<20% 红、<50% 橙、≥50% 绿
可配置边框/轨道/电量/闪电颜色;可显示百分比文本
支持无障碍(contentDescription、AccessibilityLiveRegion)
支持状态保存(旋转/进程重建)
平滑动画过渡(setLevelAnimated)
1、自定义属性res/values/attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="BatteryView"> <attr name="bv_level" format="integer"/> <attr name="bv_showPercentage" format="boolean"/> <attr name="bv_charging" format="boolean"/> <attr name="bv_fastCharging" format="boolean"/> <attr name="bv_borderColor" format="color"/> <attr name="bv_trackColor" format="color"/> <attr name="bv_fillColor" format="color"/> <attr name="bv_lowColor" format="color"/> <attr name="bv_mediumColor" format="color"/> <attr name="bv_highColor" format="color"/> <attr name="bv_boltColor" format="color"/> <attr name="bv_borderWidth" format="dimension"/> <attr name="bv_cornerRadius" format="dimension"/> <attr name="bv_capWidth" format="dimension"/> <attr name="bv_capGap" format="dimension"/> <attr name="bv_textSize" format="dimension"/> </declare-styleable> </resources>
术语说明:
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<SavedState> = object : Parcelable.Creator<SavedState> { override fun createFromParcel(source: Parcel): SavedState = SavedState(source) override fun newArray(size: Int): Array<SavedState?> = 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 用法示例
<com.yourpkg.widget.BatteryView android:id="@+id/battery" android:layout_width="120dp" android:layout_height="40dp" android:layout_margin="16dp" app:bv_level="45" app:bv_showPercentage="true" app:bv_charging="true" app:bv_fastCharging="false" app:bv_borderColor="#222222" app:bv_trackColor="#F2F2F2" app:bv_lowColor="#E53935" app:bv_mediumColor="#FB8C00" app:bv_highColor="#43A047" app:bv_boltColor="#FFFFFF" app:bv_borderWidth="2dp" app:bv_cornerRadius="8dp" app:bv_capWidth="7dp" app:bv_capGap="2dp" app:bv_textSize="12sp"/>
4、代码控制示例
val bv = findViewById<BatteryView>(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
计算)。
到此这篇关于Android自定义电池组件(BatteryView)的文章就介绍到这了,更多相关Android自定义电池组件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!