實在不知道起什么名字好了,哈哈瘦材》禄看看效果先朗和。
其實時很簡單的一個效果,但是我剛看到的時候抢蚀,哇镰禾!好神奇,怎么實現(xiàn)的啊屋休。經(jīng)過了一番思考和對自定義控件的了解劫樟,然后給他搞了出來织堂。下面我們來看看到底如何實現(xiàn)易阳。
首先你要了解自定義View的繪制的api方法,了解了這些方法就很容易實現(xiàn)了拒课。
- Canvas(畫布)
當(dāng)你調(diào)用View#onDraw()中的canvas的時候你會發(fā)現(xiàn)真的好多方法早像,功能很強(qiáng)大肖爵。它可以完成弧線(arcs)、填充顏色(argb和color)冀自、 Bitmap凡纳、圓(circle和oval)帝蒿、點(point)、線(line)延塑、矩形(Rect)答渔、圖片(Picture)、圓角矩形 (RoundRect)沼撕、文本(text)务豺、頂點(Vertices)、路徑(path)笼沥。今天在這里不會講這些啦。主要講能用到的今天項目的方法馆纳。主要是canvas.drawRect()和canvas.clicpRect
鲁驶。第一個不用多說了就是繪制一個矩形。而第二個也是顧名思義就是對矩形進(jìn)行裁剪灵嫌。那么怎么用呢寿羞,先來看一個例子绪穆。
mPaint = new Paint();
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(Color.RED);
canvas.drawRect(new RectF(0, 0, 500, 100), mPaint);
他的樣子時這樣的
然后再在添加一句代碼
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);
再看效果
你會發(fā)現(xiàn)紅條被裁剪了玖院,他的寬度就是
clicpRect()
方法中的寬度难菌〗季疲看到這里是不是一下子有了做進(jìn)度條的思路呢。沒錯就是利用這個方法一步一步的進(jìn)行裁剪就可以做出進(jìn)度條的效果啦摹闽。進(jìn)度條的效果有了付鹿,最神奇的字體進(jìn)度是怎么回事呢舵匾?其實也是用這個方法啦慢叨。一個道理拍谐,只是需要一個簡單的判斷馏段,判斷進(jìn)度何時到字體的位置院喜,然后在進(jìn)行裁剪。擼代碼:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//繪制背景
drawBackgroud(canvas);
//繪制進(jìn)度
drawProcess(canvas);
//繪制文本
drawText(canvas);
//繪制進(jìn)度文本
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);
//獲取進(jìn)度文本
String text = getProcessText();
canvas.save();
//計算坐標(biāo),使文字居中顯示
float tx = (getMeasuredWidth() - textRect.width()) / 2;
float ty = (getMeasuredHeight() + textRect.height()) / 2;
//進(jìn)度條走的進(jìn)度比例
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();
}
相信大家可以看懂里面的一些邏輯荷逞。就是在不斷的進(jìn)行裁剪實現(xiàn)進(jìn)度的刷新种远。
mProcess是外部傳進(jìn)來的進(jìn)度通過
public void setProcess(int process){
this.mProcess = process;
postInvalidate();
}
好啦顽耳,我這里就是將一個思路射富,這個例子還有很多完善的地方胰耗,大家可以自行完善就好限次。
給上Demo地址 這里