Android 自定义View 自定义动态进度圆环 动态数字显示 超级简单的方式
程序员文章站
2024-02-06 23:47:46
...
本文是根据Hencoder学习完成
效果图:
实现也很简单都写在代码注释中
xml布局代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_sports_circle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/et_progress"
android:layout_width="300dp"
android:layout_height="60dp"
android:layout_marginTop="10dp"
android:hint="请输入比例1-100"
android:inputType="number"
android:textSize="14sp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="submit"
android:text="确定" />
<com.dyjf.drawview.sports_circle.SportsCircle
android:id="@+id/sc_animation"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
自定义View SportsCircle类:
public class SportsCircle extends View {
private float progress = 0;
public SportsCircle(Context context) {
super(context);
}
public SportsCircle(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SportsCircle(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public SportsCircle(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public float getProgress() {
return progress;
}
public void setProgress(float progress) {
this.progress = progress;
//这个地方一定要调用刷新方法
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//限制progress比例最大为100
progress = progress > 100 ? 100 : progress;
//画笔设置
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.parseColor("#FFC125"));
paint.setStrokeWidth(8);
paint.setStyle(Paint.Style.STROKE);
//绘制进度圆环
RectF rectF = new RectF(50, 50, 350, 350);
canvas.drawArc(rectF, -120, (float) (progress * 3.6), false, paint);
//注意:下面这个方法也可以绘制圆环,但是在API level 21 才加入的,低版本的手机会报错,所以要小心了
// canvas.drawArc(50, 50, 350, 350, -90, (float) (progress * 3.6), false, paint);
//以下是绘制中心文本
String textProgress = (int) progress + "%";
//重新设置画笔
paint.setTextSize(60);
paint.setStrokeWidth(2);
paint.setStyle(Paint.Style.FILL);
//计算出文本在圆环中心位置坐标
float textWidth = paint.measureText(textProgress);
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
float dy = (fontMetrics.descent - fontMetrics.ascent) / 2 - fontMetrics.descent;
canvas.drawText(textProgress, 200 - textWidth / 2, 200 + dy, paint);
}
}
Activity:
public class SportsCircleActivity extends AppCompatActivity {
private SportsCircle sc_animation;
private float progress = 0;
private EditText et_progress;
private String progressString;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sports_circle);
sc_animation = ((SportsCircle) findViewById(R.id.sc_animation));
et_progress = ((EditText) findViewById(R.id.et_progress));
et_progress.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
progressString = editable.toString();
}
});
}
//点击Button确定以后执行动画
public void submit(View view) {
if (null != progressString && progressString.length() > 0)
progress = Float.parseFloat(progressString.trim());
progress = progress > 100 ? 100 : progress;
// 最后三个参数 0, progress + 20, progress,其中progress + 20是多绘制20%再回弹回来
//如果不需要回弹效果可以删除:ObjectAnimator.ofFloat(sc_animation, "progress", 0, progress);
ObjectAnimator progressAnimator
= ObjectAnimator.ofFloat(sc_animation, "progress", 0, progress + 20, progress);
progressAnimator.setDuration(1500);
progressAnimator.start();
}
}
其他细节方面可以根据自己的需求进行调整