Android自定义电池电量显示组件(kotlin,java)

最近产品研发需求需要显示在线设备的电池电量状态,然后UI给出的效果的图是这样的

于是就开始了自定义个,因为是项目特定的UI所以很多属性都没有直接抽取到styles里面了,直接上代码(因为项目是使用kotlin的,所以直接用kotlin进行编程了,当然也附带了Java版本的)

kotlin版本(里面用到的颜色值可自定义,这里是使用项目工具类转过来的):

package com.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import com.blankj.utilcode.util.ColorUtils
import com.blankj.utilcode.util.ImageUtils
import com.view.R

/**
 * @CreateDate: 
 * @Author:lp
 * @Description:
 */
class BatteryView @JvmOverloads constructor(context: Context?, attrs: AttributeSet? = null) :
    View(context, attrs) {

    private val batteryBodyPainter: Paint//电池外边框画笔
    private val batteryHeadPainter: Paint//电池盖画笔
    private val mPowerPaint: Paint//电量画笔

    private val outlineRect: RectF//电池矩形
    private val mCapRect: RectF//电池盖矩形
    private val batteryRect: RectF//电量矩形

    private var fullPowerWidth = 0f //满电量时电池体的宽度。
    private var battery = 20
    private var leftPoint = 0f
    private var topPoint = 0f

    fun setBattery(battery: Int) {
        this.battery = battery
        invalidate()
    }

    fun getBattery(): Int {
        return battery
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        val specWidthSize = MeasureSpec.getSize(widthMeasureSpec) //宽
        val specHeightSize = MeasureSpec.getSize(heightMeasureSpec) //高

        //设置电池外框
        outlineRect.right = specWidthSize - OUTLINE_THICKNESS - CAP_WIDTH
        outlineRect.bottom = specHeightSize - OUTLINE_THICKNESS

        //设置电池盖矩形
        mCapRect.left = outlineRect.right
        mCapRect.top = specHeightSize.toFloat() / 2 - CAP_HEIGHT / 2
        mCapRect.right = specWidthSize.toFloat()
        mCapRect.bottom = specHeightSize.toFloat() / 2 + CAP_HEIGHT / 2

        //设置电池体
        batteryRect.left = outlineRect.left + GAP_OF_SHAPE_BODY
        batteryRect.top = outlineRect.top + GAP_OF_SHAPE_BODY
        batteryRect.bottom = outlineRect.bottom - GAP_OF_SHAPE_BODY

        //闪电位置
        leftPoint = specWidthSize / 2 - OUTLINE_THICKNESS * 2
        topPoint = specHeightSize / 2 - OUTLINE_THICKNESS * 2
        fullPowerWidth = outlineRect.right - GAP_OF_SHAPE_BODY - batteryRect.left
        setMeasuredDimension(specWidthSize, specHeightSize)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        //设置电量矩形
        var batter = battery
        if (batter < 0) {
            batter = 50
        }
        batteryRect.right = batter.toFloat() / 100 * fullPowerWidth + batteryRect.left
        when {
            battery < 0 -> {
                batteryBodyPainter.color = ColorUtils.getColor(R.color.color_818283)
                batteryHeadPainter.color = ColorUtils.getColor(R.color.color_818283)
                mPowerPaint.color = ColorUtils.getColor(R.color.color_818283)
            }
            battery <= 20 -> {
                batteryBodyPainter.color = ColorUtils.getColor(R.color.color_818283)
                batteryHeadPainter.color = ColorUtils.getColor(R.color.color_FF4A37)
                mPowerPaint.color = ColorUtils.getColor(R.color.color_FF4A37)
            }
            battery <= 40 -> {
                batteryBodyPainter.color = ColorUtils.getColor(R.color.color_41D9B5)
                batteryHeadPainter.color = ColorUtils.getColor(R.color.color_41D9B5)
                mPowerPaint.color = ColorUtils.getColor(R.color.color_FF9037)
            }
            else -> {
                batteryBodyPainter.color = ColorUtils.getColor(R.color.color_2CBF6C)
                batteryHeadPainter.color = ColorUtils.getColor(R.color.color_2CBF6C)
                mPowerPaint.color = ColorUtils.getColor(R.color.color_2CBF6C)
            }
        }
        canvas.drawRoundRect(
            outlineRect,
            ROUND_CORNER_RADIUS,
            ROUND_CORNER_RADIUS,
            batteryBodyPainter
        )
        canvas.drawRoundRect(mCapRect, 1f, 1f, batteryHeadPainter)
        canvas.drawRoundRect(batteryRect, ROUND_CORNER_RADIUS, ROUND_CORNER_RADIUS, mPowerPaint)
        if (battery in 0..20) {
            val bitmap = ImageUtils.getBitmap(R.mipmap.shandian)
            canvas.drawBitmap(bitmap, leftPoint, topPoint, null)
        }
    }

    companion object {
        private const val OUTLINE_THICKNESS = 3.0f //电池框厚度
        private const val CAP_WIDTH = 2.0f //电池盖宽度
        private const val CAP_HEIGHT = 8.0f //电池盖高度
        private const val GAP_OF_SHAPE_BODY = 2.0f //电池体与外框之间的间隙
        private const val ROUND_CORNER_RADIUS = 2f//电池圆角
    }

    init {
        //电池外框
        batteryBodyPainter = Paint()
        batteryBodyPainter.color = ColorUtils.getColor(R.color.color_2CBF6C)
        batteryBodyPainter.isAntiAlias = true
        batteryBodyPainter.style = Paint.Style.STROKE
        batteryBodyPainter.strokeWidth = OUTLINE_THICKNESS

        //电池盖
        batteryHeadPainter = Paint()
        batteryHeadPainter.color = ColorUtils.getColor(R.color.color_FF0A0A)
        batteryHeadPainter.isAntiAlias = true
        batteryHeadPainter.style = Paint.Style.FILL

        //电量
        mPowerPaint = Paint()
        mPowerPaint.isAntiAlias = true
        mPowerPaint.color = ColorUtils.getColor(R.color.color_3C83FA)
        mPowerPaint.style = Paint.Style.FILL
        outlineRect = RectF()
        outlineRect.left = OUTLINE_THICKNESS
        outlineRect.top = OUTLINE_THICKNESS
        mCapRect = RectF()
        batteryRect = RectF()
    }
}

Java版本:

package com.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

import com.blankj.utilcode.util.ColorUtils;
import com.blankj.utilcode.util.ImageUtils;
import com.blankj.utilcode.util.ResourceUtils;
import com.view.R;

/**
 * @CreateDate: 
 * @Author:lp
 * @Description:
 */
public class BatteryView extends View {

    private static final float OUTLINE_THICKNESS = 3.0f;//电池框厚度
    private static final float CAP_WIDTH = 2.0f;//电池盖宽度
    private static final float CAP_HEIGHT = 8.0f;//电池盖高度
    private static final float GAP_OF_SHAPE_BODY = 2.0f;//电池体与外框之间的间隙
    private static final float ROUND_CORNER_RADIUS = 2;

    private float fullPowerWidth; //满电量时电池体的宽度。

    private int battery = 20;

    private Paint batteryBodyPainter;
    private Paint batteryHeadPainter;
    private Paint mPowerPaint;//电量画笔

    private RectF outlineRect;//电池矩形
    private RectF mCapRect;//电池盖矩形
    private RectF batteryRect;//电量矩形

    private int left;
    private int top;

    public BatteryView(Context context) {
        this(context, null);
    }

    public BatteryView(Context context, AttributeSet attrs) {
        super(context, attrs);
        //电池外框
        batteryBodyPainter = new Paint();
        batteryBodyPainter.setColor(ColorUtils.getColor(R.color.color_2CBF6C));
        batteryBodyPainter.setAntiAlias(true);
        batteryBodyPainter.setStyle(Paint.Style.STROKE);
        batteryBodyPainter.setStrokeWidth(OUTLINE_THICKNESS);

        //电池盖
        batteryHeadPainter = new Paint();
        batteryHeadPainter.setColor(ColorUtils.getColor(R.color.color_FF0A0A));
        batteryHeadPainter.setAntiAlias(true);
        batteryHeadPainter.setStyle(Paint.Style.FILL);

        //电量
        mPowerPaint = new Paint();
        mPowerPaint.setAntiAlias(true);
        mPowerPaint.setColor(ColorUtils.getColor(R.color.color_3C83FA));
        mPowerPaint.setStyle(Paint.Style.FILL);

        outlineRect = new RectF();
        outlineRect.left = OUTLINE_THICKNESS;
        outlineRect.top = OUTLINE_THICKNESS;

        mCapRect = new RectF();
        batteryRect = new RectF();
    }

    public void setBattery(int battery) {
//        this.battery = battery > 100 ? 100 : battery < 1 ? 1 : battery;
        this.battery = battery;
        invalidate();
    }

    public int getBattery() {
        return battery;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int specWidthSize = MeasureSpec.getSize(widthMeasureSpec);//宽
        int specHeightSize = MeasureSpec.getSize(heightMeasureSpec);//高

        //设置电池外框
        outlineRect.right = specWidthSize - OUTLINE_THICKNESS - CAP_WIDTH;
        outlineRect.bottom = specHeightSize - OUTLINE_THICKNESS;

        //设置电池盖矩形
        mCapRect.left = outlineRect.right;
        mCapRect.top = (float) specHeightSize / 2 - CAP_HEIGHT / 2;
        mCapRect.right = specWidthSize;
        mCapRect.bottom = (float) specHeightSize / 2 + CAP_HEIGHT / 2;

        //设置电池体
        batteryRect.left = outlineRect.left + GAP_OF_SHAPE_BODY;
        batteryRect.top = outlineRect.top + GAP_OF_SHAPE_BODY;
        batteryRect.bottom = outlineRect.bottom - GAP_OF_SHAPE_BODY;

        //闪电位置
        left = (int) (specWidthSize / 2 - OUTLINE_THICKNESS * 2);
        top = (int) (specHeightSize / 2 - OUTLINE_THICKNESS * 2);

        fullPowerWidth = outlineRect.right - GAP_OF_SHAPE_BODY - batteryRect.left;

        setMeasuredDimension(specWidthSize, specHeightSize);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //设置电量矩形
        int batter = battery;
        if (batter < 0) {
            batter = 50;
        }
        batteryRect.right = (float) batter / 100 * fullPowerWidth + batteryRect.left;
        if (battery < 0) {
            batteryBodyPainter.setColor(ColorUtils.getColor(R.color.color_818283));
            batteryHeadPainter.setColor(ColorUtils.getColor(R.color.color_818283));
            mPowerPaint.setColor(ColorUtils.getColor(R.color.color_818283));
        } else if (battery <= 20) {
            batteryBodyPainter.setColor(ColorUtils.getColor(R.color.color_818283));
            batteryHeadPainter.setColor(ColorUtils.getColor(R.color.color_FF4A37));
            mPowerPaint.setColor(ColorUtils.getColor(R.color.color_FF4A37));
        } else if (battery < 40) {
            batteryBodyPainter.setColor(ColorUtils.getColor(R.color.color_41D9B5));
            batteryHeadPainter.setColor(ColorUtils.getColor(R.color.color_41D9B5));
            mPowerPaint.setColor(ColorUtils.getColor(R.color.color_FF9037));
        } else {
            batteryBodyPainter.setColor(ColorUtils.getColor(R.color.color_2CBF6C));
            batteryHeadPainter.setColor(ColorUtils.getColor(R.color.color_2CBF6C));
            mPowerPaint.setColor(ColorUtils.getColor(R.color.color_2CBF6C));
        }
        canvas.drawRoundRect(outlineRect, ROUND_CORNER_RADIUS, ROUND_CORNER_RADIUS, batteryBodyPainter);
        canvas.drawRoundRect(mCapRect, 1, 1, batteryHeadPainter);
        canvas.drawRoundRect(batteryRect, ROUND_CORNER_RADIUS, ROUND_CORNER_RADIUS, mPowerPaint);
        if (battery >= 0 && battery <= 20) {
            Bitmap bitmap = ImageUtils.getBitmap(R.mipmap.shandian);
            canvas.drawBitmap(bitmap, left, top, null);
        }
    }
}

上面代码中使用到的闪电图片(当然也可以去矢量图库下载一个):

 使用:在布局文件中:

<com.view.BatteryView
      android:id="@+id/batteryVV"
      android:layout_width="26dp"
      android:layout_height="12dp"
      android:layout_marginTop="5dp" />

在代码中直接通过setBattery来设置电量(比如:batteryView.setBattery(50),设置电量为50%),因为项目需求,如果设备离线电池电量灰置(这里直接传入-1表示设备离线),如果低于20就需要增减红色闪电显示(这些都可以根据需要修改源代码),方便简洁,哈哈哈哈哈哈~

猜你喜欢

转载自blog.csdn.net/lplj717/article/details/126872722