项目需求,能显示外接设备的电量,要跟外面的妖艳贱货们差不多的效果。
简单不是么,我能直接找as生成这么多好看的图标,你怕不怕?
——不行,我要是电量21怎么办?
。。。天杀的处女座啊。
需求要和md的图标一样的风格,于是先下一个研究一下它的配色和构成
这里可以得到一个点,就是背景颜色alpha是.3,也就是77左右,
再看电池的形状,其实仔细剖析还是比较简单的:
上面一个矩形,下面一个圆角矩形
OK,思路就出来了:
- 首先定义哪些需要暴露的属性:前景色,电量百分比(int,同时设置set入口)
- 先用alpha为77的黑色画一个背景电池的形状;
- 根据传入的电量百分比裁剪画布;
- 换好前景色, 再把电池画一遍。
当然有不可避免的重绘,这里先不管了,当然有强迫症的话可以裁剪两次。。。
先是attrs声明好需要外部设置的属性:
实现View的子类,获取属性,重写onMeasure()和onDraw():
先是成员变量,这次很简单
private int battaryPercent;//电量百分比
private int color;//前景色
private float round;//圆角大小,这里写死,省去使用时计算
构造方法拿到属性
public BattaryView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.BattaryView, 0, defStyleAttr);
for (int i = 0; i < typedArray.length(); i++) {
int attr = typedArray.getIndex(i);
switch (attr) {
case R.styleable.BattaryView_battaryPercnet:
battaryPercent = typedArray.getInteger(attr, 0);
break;
case R.styleable.BattaryView_color:
color = typedArray.getColor(attr, Color.BLACK);
break;
}
}
typedArray.recycle();
mPaint = new Paint();
mPaint.setColor(color);
mPaint.setAntiAlias(true);
}
onMeasure()简单的写一下,这次就先省略了,xml里面写死(其实是发现麻烦懒得写了)
onDraw() 代码里面注解挺详细的
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
round = getHeight() / 40f;//把圆角写死,省去使用时计算
mPaint.setStyle(Paint.Style.FILL);//填充模式
//电池区域的高,宽
int imgH = getHeight() - getPaddingTop() - getPaddingBottom();
int imgW = (getWidth() < getHeight() / 2) ? (getWidth() - getPaddingLeft() - getPaddingRight()) : getHeight() / 2;
//根据电量百分比得到的矩形,top和bottom先占位,等一下再重新赋值,也可以new RectF()里面空参,四个属性挨个设置
RectF rectF = new RectF(
(float) getPaddingLeft(),
0,
(float) getPaddingLeft() + imgW,
0);
float spaceTop = (getHeight() - imgH) / 2 + getPaddingTop();
rectF.top = spaceTop + (1.0f - battaryPercent * 1.0f / 100) * imgH;
rectF.bottom = getHeight() - spaceTop;
//上面这三行其实有电多余,由于刚开始是想设置at most时的状况的,后来发现太麻烦,急着用就先这样了。
int layerId = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), null, Canvas.ALL_SAVE_FLAG);
int h1 = imgH / 8;//电池凸点的高度
int w1 = imgW / 3;//电池凸点的宽度
//绘制背景
mPaint.setColor(Color.argb(77, 0, 0, 0));
canvas.drawRoundRect(rectF.left,h1 + getPaddingTop(),rectF.right,getHeight() - getPaddingBottom(),round,round,mPaint);
canvas.drawRect(getPaddingLeft() + w1,getPaddingTop(),rectF.right - w1,h1 + getPaddingTop(),mPaint);
//绘制有电部分
canvas.save();
canvas.clipRect(rectF);
mPaint.setColor(color);
canvas.drawRoundRect(rectF.left, getPaddingTop() + h1, rectF.right, rectF.bottom, round, round, mPaint);
canvas.drawRect(rectF.left + w1, rectF.top, rectF.right - w1, getPaddingTop() + h1 + h1 / 10, mPaint);
canvas.restore();
canvas.restoreToCount(layerId);
}
好了,然后简单调用测试:
差不多,再加上set方法,试试动态设置电量看看
自定义view类里面:
public void setBattaryPercent(int battaryPercent) {
this.battaryPercent = battaryPercent;
postInvalidate();
}
activity中与seekbar结合使用,比较简单了。直接放效果:
看小图其实圆角有点小了,可以自己改一下比例。。。
源码点击查看