廢話不多說先看效果圖
原諒模擬器顯示的不好看,為了錄GIF圖,只能用模擬器
思路分析
一個背景,一個進度,一個進度值顯示,進度條與文字顯示的高度是1:2,其中用到了drawRoundRect用來畫帶圓角的矩形,空心與實心都是Paint的屬性設定的,drawText用來畫文字
注意點:
1.進度條進度滿進度與未滿進度,計算onewidth = mwidth / mMaxProgress(單位進度佔的寬度=總寬度/滿進度);
2.文字顯示,先計算文字的寬度,三個狀態(起始位置 <= 文字寬度 / 當前位置 +文字寬度>=寬度/之間的),分別進行計算
實現
onDraw來畫圖了
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float x = onewidth * mCurrentProgress;
//畫背景
RectF rectF = new RectF(0, 0, mwidth, bheight);
canvas.drawRoundRect(rectF, num8, num8, backgroudPaint);
//畫進度條
RectF rectFm;
if (mCurrentProgress == mMaxProgress) {
rectFm = new RectF(num2, num2, mwidth - num2, bheight - num2);
} else {
rectFm = new RectF(num2, num2, x + num2, bheight - num2);
}
canvas.drawRoundRect(rectFm, num8, num8, mPaint);
//畫文字
//獲取文字的寬度及其高度
Rect rect = new Rect();
String speed = mCurrentProgress + "%";
txtPaint.getTextBounds(speed, 0, speed.length(), rect);
textheight = rect.height();
textwidth = rect.width();
if (mCurrentProgress == mMaxProgress) {
canvas.drawText(speed, mwidth - textwidth, txtheight, txtPaint);
} else {
//起始位置 <= 文字寬度
if (x <= textwidth) {
canvas.drawText(speed, textwidth / 2, txtheight, txtPaint);
//當前位置 +文字寬度>=寬度
} else if (x + textwidth >= mwidth) {
canvas.drawText(speed, mwidth - textwidth - 2 * num8, txtheight, txtPaint);
} else {
canvas.drawText(speed, x - textwidth / 2, txtheight, txtPaint);
}
}
}複製程式碼
設定進度
public void setProgress(int progress) {
if (progress <= 100 && progress >= 0) {
this.mCurrentProgress = progress;
invalidate();
}
}複製程式碼
實際專案中,可有很多的擴充套件,但是有時候實際專案不需要把很多不需要的方法,設定屬性的方法等給寫出來,根據專案的需求去寫相關方法、屬性設定
完整程式碼
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.numberview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by wujun on 2017/9/20.
*
* @author madreain
* @desc
*/
public class NumberView1 extends View {
Paint backgroudPaint;
Paint mPaint;
Paint txtPaint;
//寬高
int mwidth, mheight;
int bheight, txtheight;
private int mMaxProgress = 100;
private int mCurrentProgress = 0;
private float onewidth;
//文字顯示的寬高
int textheight;
int textwidth;
float num8;
float num2;
// 30 10 20
public NumberView1(Context context) {
super(context);
init();
}
public NumberView1(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public NumberView1(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
backgroudPaint = new Paint();
backgroudPaint.setAntiAlias(true);
backgroudPaint.setStyle(Paint.Style.STROKE);
backgroudPaint.setStrokeCap(Paint.Cap.ROUND);
backgroudPaint.setColor(Color.rgb(51, 197, 167));
txtPaint = new Paint();
txtPaint.setAntiAlias(true);
txtPaint.setStyle(Paint.Style.FILL);
txtPaint.setColor(Color.rgb(51, 197, 167));
txtPaint.setTextSize(sp2px(12));
txtPaint.setStrokeWidth(2);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setColor(Color.rgb(51, 197, 167));
num8 = dp2px(8);
num2 = dp2px(2);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mwidth = w;
mheight = h;
bheight = mheight / 3;
txtheight = bheight * 2;
onewidth = mwidth / mMaxProgress;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float x = onewidth * mCurrentProgress;
//畫背景
RectF rectF = new RectF(0, 0, mwidth, bheight);
canvas.drawRoundRect(rectF, num8, num8, backgroudPaint);
//畫進度條
RectF rectFm;
if (mCurrentProgress == mMaxProgress) {
rectFm = new RectF(num2, num2, mwidth - num2, bheight - num2);
} else {
rectFm = new RectF(num2, num2, x + num2, bheight - num2);
}
canvas.drawRoundRect(rectFm, num8, num8, mPaint);
//畫文字
//獲取文字的寬度及其高度
Rect rect = new Rect();
String speed = mCurrentProgress + "%";
txtPaint.getTextBounds(speed, 0, speed.length(), rect);
textheight = rect.height();
textwidth = rect.width();
if (mCurrentProgress == mMaxProgress) {
canvas.drawText(speed, mwidth - textwidth, txtheight, txtPaint);
} else {
//起始位置 <= 文字寬度
if (x <= textwidth) {
canvas.drawText(speed, textwidth / 2, txtheight, txtPaint);
//當前位置 +文字寬度>=寬度
} else if (x + textwidth >= mwidth) {
canvas.drawText(speed, mwidth - textwidth - 2 * num8, txtheight, txtPaint);
} else {
canvas.drawText(speed, x - textwidth / 2, txtheight, txtPaint);
}
}
}
public float dp2px(float dp) {
final float scale = getResources().getDisplayMetrics().density;
return dp * scale + 0.5f;
}
public float sp2px(float sp) {
final float scale = getResources().getDisplayMetrics().scaledDensity;
return sp * scale;
}
public void setProgress(int progress) {
if (progress <= 100 && progress >= 0) {
this.mCurrentProgress = progress;
invalidate();
}
}
}複製程式碼
自定義view多寫多練