实在不知道起什么名字好了,哈哈。看看效果先。
ezgif-4-8120c9098c.gif其实时很简单的一个效果,但是我刚看到的时候,哇!好神奇,怎么实现的啊。经过了一番思考和对自定义控件的了解,然后给他搞了出来。下面我们来看看到底如何实现。
首先你要了解自定义View的绘制的api方法,了解了这些方法就很容易实现了。
- Canvas(画布)
当你调用View#onDraw()中的canvas的时候你会发现真的好多方法,功能很强大。它可以完成弧线(arcs)、填充颜色(argb和color)、 Bitmap、圆(circle和oval)、点(point)、线(line)、矩形(Rect)、图片(Picture)、圆角矩形 (RoundRect)、文本(text)、顶点(Vertices)、路径(path)。今天在这里不会讲这些啦。主要讲能用到的今天项目的方法。主要是canvas.drawRect()和canvas.clicpRect
。第一个不用多说了就是绘制一个矩形。而第二个也是顾名思义就是对矩形进行裁剪。那么怎么用呢,先来看一个例子。
mPaint = new Paint();
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(Color.RED);
canvas.drawRect(new RectF(0, 0, 500, 100), mPaint);
他的样子时这样的
test1.png
然后再在添加一句代码
mPaint = new Paint();
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(Color.RED);
canvas.clipRect(new RectF(0, 0, 200, 100));
canvas.drawRect(new RectF(0, 0, 500, 100), mPaint);
再看效果
test2.png你会发现红条被裁剪了,他的宽度就是
clicpRect()
方法中的宽度。看到这里是不是一下子有了做进度条的思路呢。没错就是利用这个方法一步一步的进行裁剪就可以做出进度条的效果啦。进度条的效果有了,最神奇的字体进度是怎么回事呢?其实也是用这个方法啦。一个道理,只是需要一个简单的判断,判断进度何时到字体的位置,然后在进行裁剪。撸代码:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//绘制背景
drawBackgroud(canvas);
//绘制进度
drawProcess(canvas);
//绘制文本
drawText(canvas);
//绘制进度文本
drawProcessText(canvas);
}
整体的代码逻辑就在这了。总共就分为这四个部分,利用canvas.drawRect()和canvas.clicpRect
方法,加上一些有效性的判断就完全可以啦。具体的判断就很简单啦。我这里就直接伤代码了。
private void drawBackgroud(Canvas canvas) {
pgPaint.setColor(Color.GREEN);
canvas.drawRoundRect(pgRect, radius, radius, pgPaint);
}
private void drawProcess(Canvas canvas) {
processPaint.setColor(Color.GREEN);
canvas.save(Canvas.CLIP_SAVE_FLAG);
int right = (int) (mProcess / mMaxProcess * getMeasuredWidth());
canvas.clipRect(pgRect.left, pgRect.top, right, pgRect.bottom);
canvas.drawRoundRect(pgRect, radius, radius, processPaint);
canvas.restore();
}
private void drawText(Canvas canvas) {
processPaint.setColor(Color.GREEN);
String text = getProcessText();
processPaint.getTextBounds(text, 0, text.length(), textRect);
processPaint.setTextSize(50);
float tx = (getMeasuredWidth() - textRect.width()) / 2;
float ty = (getMeasuredHeight() + textRect.height()) / 2;
canvas.drawText(text, tx, ty, processPaint);
}
private void drawProcessText(Canvas canvas) {
processPaint.setColor(Color.WHITE);
//获取进度文本
String text = getProcessText();
canvas.save();
//计算坐标,使文字居中显示
float tx = (getMeasuredWidth() - textRect.width()) / 2;
float ty = (getMeasuredHeight() + textRect.height()) / 2;
//进度条走的进度比例
int right = (int) (mProcess / mMaxProcess * getMeasuredWidth());
//判断是否到了字体的位置。
if(tx <= right){
canvas.clipRect(textRect.left, textRect.top, right, textRect.right);
canvas.drawText(text, tx, ty, processPaint);
}
canvas.restore();
}
相信大家可以看懂里面的一些逻辑。就是在不断的进行裁剪实现进度的刷新。
mProcess是外部传进来的进度通过
public void setProcess(int process){
this.mProcess = process;
postInvalidate();
}
好啦,我这里就是将一个思路,这个例子还有很多完善的地方,大家可以自行完善就好。
给上Demo地址 这里
网友评论