Android之View 提升: 六 自定义进度条
一 知识点
- 重写3个方法:
onSizeChanged
, onDraw
, onMeasure
,实现数字随着进度条移动 - 自定义数字,使用Paint进行数字的绘制
二 实现效果
三 实现代码
- view文件
package cn.study.myapplication;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.ProgressBar;
public class MyProgressView extends ProgressBar {
protected Paint mPaint = new Paint();
protected int mTextColor = 0XFF008000;
protected int mTextSize = 60;
protected int mTextOffset = 60;
protected int mLeftHeight = 5;
protected int mLeftColor = 0XFF0000FF;
protected int mRightHeight = 15;
protected int mRightColor = 0XFFFF0000;
protected int mRealWidth;
protected boolean isDraw = true;
public MyProgressView(Context context, AttributeSet attrs) {
this(context,attrs,0);
}
public MyProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setHorizontalScrollBarEnabled(true);
mPaint.setTextSize(mTextSize);
mPaint.setColor(mTextColor);
}
@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int mMode = MeasureSpec.getMode(heightMeasureSpec);
if(mMode!=MeasureSpec.EXACTLY){
float mHeight = (mPaint.descent() + mPaint.ascent());
int mExceptHeight = (int)(getPaddingTop()+getPaddingBottom()+Math.max(Math.max(mLeftHeight,mRightHeight),Math.abs(mHeight)));
heightMeasureSpec = MeasureSpec.makeMeasureSpec(mExceptHeight, MeasureSpec.EXACTLY);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected synchronized void onDraw(Canvas canvas) {
canvas.translate(getPaddingLeft(),getHeight()/2);
boolean isNeed = false;
float mRatio = getProgress() * 1.0f / getMax();
float mPosx = (int)(mRealWidth * mRatio);
String mText = String.valueOf(getProgress()) + "%";
float mTextWidth = mPaint.measureText(mText);
float mTextHeight = (mPaint.descent()+mPaint.ascent())/2;
if(mPosx + mTextWidth > mRealWidth){
mPosx = mRealWidth - mTextWidth;
isNeed = true;
}
float mEndx = mPosx - mTextOffset / 2;
if(mEndx > 0){
mPaint.setColor(mLeftColor);
mPaint.setStrokeWidth(mLeftHeight);
canvas.drawLine(0,0,mEndx,0,mPaint);
}
if(isDraw){
mPaint.setColor(mTextColor);
canvas.drawText(mText,mPosx,-mTextHeight,mPaint);
}
if(!isNeed){
float start = mPosx + mTextOffset/2 + mTextWidth;
mPaint.setColor(mRightColor);
mPaint.setStrokeWidth(mRightHeight);
canvas.drawLine(start, 0 , mRealWidth, 0, mPaint);
}
super.onDraw(canvas);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mRealWidth = w-getPaddingRight() - getPaddingLeft();
}
}
- MainActivity 中调用
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyProgressView myProgressView = findViewById(R.id.mprogress);
int MAX_PROGRESS = 100;
myProgressView.setMax(MAX_PROGRESS);
new Thread(new Runnable() {
@Override
public void run() {
int progress = 0;
while(progress < MAX_PROGRESS){
try {
Thread.sleep(MAX_PROGRESS);
progress++;
myProgressView.incrementProgressBy(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
- layout文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<cn.study.myapplication.MyProgressView
android:layout_marginTop="300dp"
android:layout_marginStart="20dp"
android:layout_width="200dp"
android:layout_height="30dp"
android:id="@+id/mprogress"/>
</LinearLayout>