小知识,大挑战!本文正在参与「程序员必备小知识」创作活动
本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。
前言
在一些阅读软件的阅读页总是会有电池的图标,他会随着我们手机电量的改变而改变,你也许会想到找UI要个图不就完了? 手机有100的电量,你总不能要100个图片吧,这一次我们使用自定义View来实现这种需求.
首先我们来看看其他app做的啥样吧
这个app叫阅读
感觉写的贼牛,特别是换源,完全避免了版权问题,不过作者好像也没有拿这个app盈利
感觉现在起点
就跟斗鱼,虎牙似的,完全没有了阅读的氛围,充满了金钱的味道....
总体分析,阅读的电池最好做,随便去个外国网站搜一个空心的电池框,里面填上还剩多少电就完事了.起点的电池相对来说比较麻烦,里面是一个矩形,需要根据电量的不同来绘制不同的长度,比较麻烦点,今天我们就挑着麻烦的做吧
首先我们先定义一些必要的属性吧
public class BatteryView extends View {
private int width, height;
// 电池外框
private int borderWidth;
// 电池与边框的间距
private int mMargin = 4;
// 颜色
private int backgroundColor;
// 电池电量
private int batteryLevel = 0;
// 电池头
private RectF headRect;
// 边框画笔
private Paint paint = new Paint();
//电池芯画笔
private Paint insidePaint = new Paint();
public BatteryView(Context context) {
this(context, null);
}
public BatteryView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public BatteryView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
borderWidth = ImageUtil.dp2px(context, 2);
height = ImageUtil.dp2px(context, 10);
width = height * 2;
}
}
没啥好说的,就是一些宽高,画笔,颜色,间距之类的
private void init(Context context) {
paint.setAntiAlias(true);
insidePaint.setAntiAlias(true);
// 电池头
int headHeight = height / 2;
headRect = new RectF(width, (height - headHeight) / 2,
width + borderWidth, (height - headHeight) / 2 + headHeight);
}
初始化一下.
paint.setAntiAlias(true);
insidePaint.setAntiAlias(true);
这两行设置电池边框和电池芯的画笔为抗锯齿,不然边边就跟狗啃了似的.
int headHeight = height / 2;
headRect = new RectF(width, (height - headHeight) / 2,
width + borderWidth, (height - headHeight) / 2 + headHeight);
这个设置的是我们电池头的位置,间距,宽高,RectF
的第一个参数是左边框距离父布局左边的距离,第三个参数是右边框距离父布局左边的距离,这就组成了我们矩形的宽度.第二个参数是上边框距离父布局上面的距离,第四个参数是下边框距离父布局上面的距离,组成了矩形的高度.
既然是自定义View那我们肯定要吧设置的参数给绘制上去,来重写onDraw
吧
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (width == 0 || mMargin == 0 || batteryLevel == 0) {
return;
}
// 画笔
paint.setColor(backgroundColor == 0 ? Color.BLACK : backgroundColor);
// 实心
paint.setStyle(Paint.Style.STROKE);
// 绘制外框
RectF externalRect = new RectF(0, 0, width, height);
canvas.drawRect(externalRect, paint);
//画电池芯
insidePaint.setColor(paint.getColor());
//根据设置batteryLevel来确定我们要绘制的电量宽度
int insideWidth = (width - mMargin) * batteryLevel / 100;
Rect rect = new Rect(mMargin, mMargin,
insideWidth + 1, height - mMargin + 1);
canvas.drawRect(rect, insidePaint);
// 画电池头
paint.setStyle(Paint.Style.FILL);
canvas.drawRect(headRect, paint);
}
这个实在没什么好讲,也就绘制电量矩形的那个地方比较难懂,就这么多.
基本的绘制已经完成,接下来我们要设置一个公共方法来设置电量参数
public void setLevelAndColor(int batteryLevel, int backgroundColor) {
this.batteryLevel = batteryLevel;
this.backgroundColor = backgroundColor;
invalidate();
}
第一个参数就是我们的电量,第二个就是电池的颜色,下面是全部代码
public class BatteryView extends View {
private int width, height;
// 电池外框
private int borderWidth;
// 电池与边框的间距
private int mMargin = 4;
// 颜色
private int backgroundColor;
// 电池电量
private int batteryLevel = 0;
// 电池头
private RectF headRect;
// 画笔
private Paint paint = new Paint();
private Paint insidePaint = new Paint();
public BatteryView(Context context) {
this(context, null);
}
public BatteryView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public BatteryView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
borderWidth = ImageUtil.dp2px(context, 2);
height = ImageUtil.dp2px(context, 10);
width = height * 2;
init(context);
}
private void init(Context context) {
paint.setAntiAlias(true);
insidePaint.setAntiAlias(true);
// 电池头
int headHeight = height / 2;
headRect = new RectF(width, (height - headHeight) / 2,
width + borderWidth, (height - headHeight) / 2 + headHeight);
}
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (width == 0 || mMargin == 0 || batteryLevel == 0) {
return;
}
// 画笔
paint.setColor(backgroundColor == 0 ? Color.BLACK : backgroundColor);
// 实心
paint.setStyle(Paint.Style.STROKE);
// 绘制外框
RectF externalRect = new RectF(0, 0, width, height);
canvas.drawRect(externalRect, paint);
//画电池芯
insidePaint.setColor(paint.getColor());
//根据设置batteryLevel来确定我们要绘制的电量宽度
int insideWidth = (width - mMargin) * batteryLevel / 100;
Rect rect = new Rect(mMargin, mMargin,
insideWidth + 1, height - mMargin + 1);
canvas.drawRect(rect, insidePaint);
// 画电池头
paint.setStyle(Paint.Style.FILL);
canvas.drawRect(headRect, paint);
}
/******************************** 公共方法 *******************************/
public void setLevelAndColor(int batteryLevel, int backgroundColor) {
this.batteryLevel = batteryLevel;
this.backgroundColor = backgroundColor;
invalidate();
}
}
一起看看效果吧
第一次打开是系统的电量,第二次我设置了10.
好了 就是这么简单,拜拜┏(^0^)┛