最近,app中要显示一个状态栏,包含,网络状态,时间和电量状态
想偷个懒,找个自定义电量项目,找了半天,没有想要的效果
只能,自己手动写一个了
代码比较简单:
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.*
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.util.Log
import android.view.View
import androidx.core.content.ContextCompat
import com.lantu.demo.R
import kotlin.properties.Delegates
/**
* 创建日期:2021/12/8 13:21
* 包名: com.lantu.demo.view
* @author queyl
* 类说明:
*
*/
class BatteryView(mContext: Context?, attrs: AttributeSet?, defStyleAttr: Int) :
View(mContext, attrs, defStyleAttr) {
companion object {
val TAG = BatteryView::class.java.simpleName
val Header_Height_Percent = 0.35f
val Header_Width_Percent = 0.1f
val Max_Power = 100
val Inside_margin = 3
val stokeWidth = 2f
val redius = 4f
}
private lateinit var paintBorder: Paint
private lateinit var paintFill: Paint
private lateinit var paintFillCharging: Paint
// 头部尺寸
private var headerHeight: Float = 0f
private var headerWidth: Float = 0f
//电量
private var mPower = 100
//是否在充电
private var isCharging = false
private var lowerPower:Int = 20
private var chargingDrawable: Int = R.drawable.charging_2
private var lowColor: Int = R.color.red_f00
private var chargingColor: Int = R.color.green_0f4
private var defaultColor: Int = R.color.black
@SuppressLint("ResourceAsColor")
@JvmOverloads
constructor(context: Context?, attrs: AttributeSet? = null) : this(context, attrs, 0) {
val ta = context?.obtainStyledAttributes(attrs, R.styleable.BatteryView)
if (ta != null) {
chargingDrawable = ta.getResourceId(R.styleable.BatteryView_charging_image, R.drawable.charging_2)
lowColor = ta.getResourceId(R.styleable.BatteryView_low_power_color, R.color.red_f00)
chargingColor = ta.getResourceId(R.styleable.BatteryView_charging_color, R.color.green_0f4)
defaultColor = ta.getResourceId(R.styleable.BatteryView_default_color, R.color.black)
lowerPower = ta.getInteger(R.styleable.BatteryView_low_power, 20)
}
ta?.recycle()
initPaint()
}
private fun initPaint() {
//先画外框
paintBorder = Paint()
paintBorder.color = Color.BLACK
paintBorder.strokeWidth = stokeWidth
paintBorder.isAntiAlias = true
paintBorder.style = Paint.Style.STROKE
//内部电量
paintFill = Paint()
paintFill.isAntiAlias = true
paintFill.style = Paint.Style.FILL
//内部电量-充电中
paintFillCharging = Paint()
paintFillCharging.color = ContextCompat.getColor(context, chargingColor)
paintFillCharging.isAntiAlias = true
paintFillCharging.style = Paint.Style.FILL
}
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
super.onLayout(changed, left, top, right, bottom)
if (changed) {
Log.d(TAG, " onLayout ==> left = ${left}, right = $right, top = $top, bottom = $bottom")
headerHeight = (bottom - top) * Header_Height_Percent
headerWidth = (right - left) * Header_Width_Percent
}
}
@SuppressLint("DrawAllocation")
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
//画电量边框
val rect = RectF(
0F, 0F,
width - headerWidth, height.toFloat()
);
canvas?.drawRoundRect(rect, redius, redius, paintBorder)
//画电池头
val rect3 =
RectF(width - headerWidth, (height / 2 - headerHeight / 2), width.toFloat(), height / 2 + headerHeight / 2)
canvas?.drawRect(rect3, paintFill);
val power_percent = (mPower * 1.0f / Max_Power)
//画电量
if (power_percent != 0F) {
val p_left = 0 + Inside_margin
val p_top = 0 + Inside_margin
val p_right = p_left + ((width - headerWidth - Inside_margin - p_left) * power_percent)
val p_bottom = height - Inside_margin
val rect2 = RectF(p_left.toFloat(), p_top.toFloat(), p_right, p_bottom.toFloat())
if (isCharging) {
canvas?.drawRect(rect2, paintFillCharging)
val options = BitmapFactory.Options()
val chargingBitmap = BitmapFactory.decodeResource(resources, chargingDrawable, options)
if ( chargingBitmap != null) {
val size = height- Inside_margin*2
canvas?.drawBitmap(
chargingBitmap,
Rect(0, 0, options.outWidth, options.outHeight),
RectF((width / 2 - size / 2f), Inside_margin.toFloat(), (width / 2 + size / 2f), height.toFloat()- Inside_margin),
paintBorder
)
}
} else {
if (mPower<=lowerPower){
paintFill.color = ContextCompat.getColor(context,lowColor)
}else{
paintFill.color = ContextCompat.getColor(context,defaultColor)
}
canvas?.drawRect(rect2, paintFill)
}
}
}
fun setPower(power: Int, charging: Boolean = false) {
if (power < 0) {
this.mPower = 0
} else if (power > Max_Power) {
mPower = Max_Power
} else {
mPower = power
}
this.isCharging = charging
invalidate()
}
}
其中用到的资源:
R.drawable.charging_2:
<color name="red_f00">#FF0000</color>
<color name="green_0f4">#00ff44</color>
<color name="black">#FF000000</color>
自定义属性:
<declare-styleable name="BatteryView">
<attr name="default_color" format="reference|color"/>
<attr name="charging_color" format="reference|color"/>
<attr name="low_power_color" format="reference|color"/>
<attr name="low_power" format="integer"/>
<attr name="charging_image" format="reference"/>
</declare-styleable>
布局引用:
<com.test.demo.view.BatteryView
android:id="@+id/battery"
android:layout_width="40dp"
android:layout_height="20dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginTop="10dp"
app:low_power_color="@color/red_f00"
app:charging_color="@color/green_0f4"
app:default_color="@color/black"
app:charging_image="@drawable/charging_3"
app:low_power="30"
/>
该自定义电量View主要功能有:
1.显示当前电量
2.显示是否在充电状态
3.设置低电量状态
如果你的需求不一样,或者有微差,自己考下代码,改动一下,比较简单
|