1. 思路分析
自定义View步骤:
1>:values__attrs.xml,自定义属性;
2>:在第三个构造方法中,获取自定义属性;
3>:onMeasure:不是非必须的,测量控件大小;
4>:onDraw:所有绘制代码都写在onDraw方法中;
思路分析
1>:自定义属性:内圆颜色、外圆颜色、圆弧宽度、中间文字颜色、文字大小;
2>:自定义ProgressBar,继承View;
2. 效果图如下
3. 代码如下
1>:attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ProgressBar">
<attr name="innerBackground" format="color"/>
<attr name="outterBackground" format="color"/>
<attr name="roundWidth" format="dimension"/>
<attr name="progressTextSize" format="dimension"/>
<attr name="progressTextColor" format="color"/>
</declare-styleable>
</resources>
2>:ProgressBar
package com.example.view05_day;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import androidx.annotation.Nullable;
public class ProgressBar extends View {
private int innerColor = Color.BLACK;
private int outColor = Color.RED;
private int mTextSize = 15;
private int mTextColor = Color.BLACK;
private int mRoundWidth = 20;
private int currentProgress = 50;
private int maxNum = 100;
private Paint innerPaint, outerPaint, mPaintText;
public ProgressBar(Context context) {
this(context, null);
}
public ProgressBar(Context context, @Nullable @org.jetbrains.annotations.Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public ProgressBar(Context context, @Nullable @org.jetbrains.annotations.Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ProgressBar);
innerColor = array.getColor(R.styleable.ProgressBar_innerBackground, innerColor);
outColor = array.getColor(R.styleable.ProgressBar_outterBackground, outColor);
mTextSize = array.getDimensionPixelSize(R.styleable.ProgressBar_progressTextSize,sp2px(mTextSize));
mRoundWidth = (int)array.getDimension(R.styleable.ProgressBar_roundWidth, dip2px(mRoundWidth));
mTextColor = array.getColor(R.styleable.ProgressBar_progressTextColor, mTextColor);
array.recycle();
innerPaint = new Paint();
innerPaint.setAntiAlias(true);
innerPaint.setColor(innerColor);
innerPaint.setStrokeWidth(mRoundWidth);
innerPaint.setStyle(Paint.Style.STROKE);
outerPaint = new Paint();
outerPaint.setAntiAlias(true);
outerPaint.setColor(outColor);
outerPaint.setStrokeWidth(mRoundWidth);
outerPaint.setStyle(Paint.Style.STROKE);
mPaintText = new Paint();
mPaintText.setAntiAlias(true);
mPaintText.setColor(mTextColor);
mPaintText.setTextSize(mTextSize);
}
private int sp2px(int sp) {
return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, getResources().getDisplayMetrics());
}
private int dip2px(int dip) {
return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, getResources().getDisplayMetrics());
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//只保证正方形
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(Math.min(width, height), Math.min(width, height));
}
@Override
protected void onDraw(Canvas canvas) {
//先画内圆
int center = getWidth()/2;
int radius = center - mRoundWidth/2;
canvas.drawCircle(center,center,radius,innerPaint);
//再画外圆,画圆弧
RectF rectF = new RectF(0+mRoundWidth/2,0+mRoundWidth/2,getWidth()-mRoundWidth/2,getHeight()-mRoundWidth/2);
if (currentProgress == 0) {
return;
}
float percent = (float)currentProgress/maxNum;
canvas.drawArc(rectF,0, 360 * percent, false, outerPaint);
//画进度文字
String text = ((int)(percent * 100)) + "%";
Rect bounds = new Rect();
mPaintText.getTextBounds(text,0,text.length(),bounds);
int x = getWidth()/2 - bounds.width()/2;
Paint.FontMetrics fontMetrics = mPaintText.getFontMetrics();
int dy = (int)((fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom);
int baseline = getHeight()/2 + dy;
canvas.drawText(text,x,baseline,mPaintText);
}
//给几个方法
public synchronized void setMax (int max) throws IllegalArgumentException{
if (max < 0) {
throw new IllegalArgumentException("FUCK YOU");
}
this.maxNum = max;
}
public synchronized void setProgress (int progress) throws IllegalArgumentException{
if (progress < 0) {
throw new IllegalArgumentException("progress error");
}
this.currentProgress = progress;
invalidate();
}
}
3>activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:paddingTop="16dp"
tools:context=".MainActivity">
<com.example.view05_day.ProgressBar
android:id="@+id/ProgressBar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:progressTextColor="@color/teal_700"
app:innerBackground= "@color/black"
app:outterBackground="@color/purple_200"
app:progressTextSize="20dp"
app:roundWidth = "20dp"/>
</RelativeLayout>
4>:MainActivity.java
package com.example.view05_day;
import androidx.appcompat.app.AppCompatActivity;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
public class MainActivity extends AppCompatActivity {
private ShapeView mShapeView;
private static final String TAG = "wqq";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ProgressBar mProgressBar = findViewById(R.id.ProgressBar);
mShapeView = findViewById(R.id.shapView);
try {
mProgressBar.setMax(4000);
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
ValueAnimator animator = ObjectAnimator.ofFloat(0,4000);
animator.setDuration(2000);
animator.start();
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float progress = (float)animation.getAnimatedValue();
try {
mProgressBar.setProgress((int)progress);
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
});
}
public void exchange(View view)
{
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
mShapeView.exchange();
Log.e(TAG, "run: wqq");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}