自定义view--进度

效果图:

这里写图片描述

自定义view:

import android.animation.FloatEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.BounceInterpolator;

public class HalfProgressView extends View {

    private static final int DEFAULT_WIDTH = 300;
    private static final int DEFAULT_HEIGHT = 300;

    private Paint inner_progress_paint, outer_bg_paint, outer_progress_paint, inner_bg_paint;
    private Paint top_text_paint, bottom_text1_paint, bottom_text2_paint;

    private RectF inner_rect, outer_rect;
    private Float value = 100F;
    private int width;
    private int height;

    private String top_txt;
    private String bottom_txt1;
    private String bottom_txt2;

    private float top_text_size;
    private int topTextWidth;
    private int bottomText1Width;

    public HalfProgressView(Context context) {
        super(context);
        init();
    }

    public HalfProgressView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public HalfProgressView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public void init() {
        inner_progress_paint = new Paint();
        inner_progress_paint.setAntiAlias(true);
        inner_progress_paint.setColor(Color.WHITE);
        inner_progress_paint.setStyle(Style.STROKE);
        inner_progress_paint.setStrokeCap(Paint.Cap.ROUND);

        outer_bg_paint = new Paint();
        outer_bg_paint.setAntiAlias(true);
        outer_bg_paint.setColor(Color.parseColor("#c2edff"));
        outer_bg_paint.setStyle(Style.STROKE);
        outer_bg_paint.setStrokeCap(Paint.Cap.ROUND);

        outer_progress_paint = new Paint();
        outer_progress_paint.setAntiAlias(true);
        outer_progress_paint.setColor(Color.WHITE);
        outer_progress_paint.setStyle(Style.STROKE);
        outer_progress_paint.setStrokeCap(Paint.Cap.ROUND);

        inner_bg_paint = new Paint();
        inner_bg_paint.setAntiAlias(true);
        inner_bg_paint.setColor(Color.parseColor("#c2edff"));
        inner_bg_paint.setStyle(Style.STROKE);
        inner_bg_paint.setStrokeCap(Paint.Cap.ROUND);

        top_text_paint = new Paint();
        top_text_paint.setAntiAlias(true);
        top_text_paint.setColor(Color.parseColor("#666666"));

        bottom_text1_paint = new Paint();
        bottom_text1_paint.setAntiAlias(true);
        bottom_text1_paint.setColor(Color.parseColor("#ff0000"));
        bottom_text1_paint.setTextAlign(Paint.Align.RIGHT);//从右开始

        bottom_text2_paint = new Paint();
        bottom_text2_paint.setAntiAlias(true);
        bottom_text2_paint.setColor(Color.parseColor("#ff0000"));
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = getProperSize(DEFAULT_WIDTH, widthMeasureSpec);
        int height = getProperSize(DEFAULT_HEIGHT, heightMeasureSpec);
        int result = Math.min(width, height);
        setMeasuredDimension(result, result);
    }

    private int getProperSize(int defaultSize, int measureSpec) {
        int result;
        int mode = MeasureSpec.getMode(measureSpec);
        int size = MeasureSpec.getSize(measureSpec);

        if (mode == MeasureSpec.EXACTLY) {
            result = size;
        } else {
            result = defaultSize;
            if (mode == MeasureSpec.AT_MOST) {
                result = Math.min(result, size);
            }
        }

        return result;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        width = w;
        height = h;

        // 大小
        float inner_stroke_width = h * 0.105f;
        float outer_stroke_width = h * 0.017f;
        inner_progress_paint.setStrokeWidth(inner_stroke_width);
        outer_progress_paint.setStrokeWidth(outer_stroke_width);
        outer_bg_paint.setStrokeWidth(outer_stroke_width);
        inner_bg_paint.setStrokeWidth(inner_stroke_width);

        top_text_size = h * 0.027f;
        float bottom_text1_size = h * 0.052f;
        float bottom_text2_size = h * 0.032f;
        top_text_paint.setTextSize(dip2px(getContext(), top_text_size));
        topTextWidth = (int) top_text_paint.measureText(top_txt);
        bottomText1Width = (int) bottom_text1_paint.measureText(bottom_txt1);
        bottom_text1_paint.setTextSize(dip2px(getContext(), bottom_text1_size));
        bottom_text2_paint.setTextSize(dip2px(getContext(), bottom_text2_size));

        // 半径
        float inner_circle_radius = h * 0.40f;
        float outer_circle_radius = h * 0.48f;

        //矩形起点y坐标
        float inner_start_y = h / 2 - inner_circle_radius;
        float outer_start_y = h / 2 - outer_circle_radius;

        LinearGradient inner_progress_shader = new LinearGradient(w / 2 - inner_circle_radius, inner_start_y,
                w / 2 - inner_circle_radius + inner_circle_radius * 2, 0,
                new int[]{Color.parseColor("#f50a0a"), Color.parseColor("#FFA500"), Color.parseColor("#fed947")},
                null,
                Shader.TileMode.CLAMP);
        inner_progress_paint.setShader(inner_progress_shader);

        LinearGradient outer_progress_shader = new LinearGradient(w / 2 - outer_circle_radius, outer_start_y,
                w / 2 - outer_circle_radius + outer_circle_radius * 2, 0,
                new int[]{Color.parseColor("#f50a0a"), Color.parseColor("#FFA500"), Color.parseColor("#fed947")},
                null,
                Shader.TileMode.CLAMP);
        outer_progress_paint.setShader(outer_progress_shader);

        inner_rect = new RectF(w / 2 - inner_circle_radius,
                inner_start_y,
                w / 2 - inner_circle_radius + inner_circle_radius * 2,
                inner_start_y + inner_circle_radius * 2);

        outer_rect = new RectF(w / 2 - outer_circle_radius,
                outer_start_y,
                w / 2 - outer_circle_radius + outer_circle_radius * 2,
                outer_start_y + outer_circle_radius * 2);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawArc(outer_rect, 130, 280, false, outer_bg_paint);//背景外环
        canvas.drawArc(inner_rect, 130, 280, false, inner_bg_paint);//背景内环

        float sweepAngle = (280 * value / 100) == 0 ? 1f : (280 * value / 100);
        canvas.drawArc(outer_rect, 130, sweepAngle, false, outer_progress_paint);//进度外环
        canvas.drawArc(inner_rect, 130, sweepAngle, false, inner_progress_paint);//进度内环

        canvas.drawLine(width / 2, 0, width / 2, height, top_text_paint);//用于观察文字位置

        canvas.drawText(top_txt, width / 2 - topTextWidth / 2, height / 2 - top_text_size * 5, top_text_paint);
        canvas.drawText(bottom_txt1, width / 2 - bottomText1Width / 2 + (int) (top_text_size * 1.5), height / 2 + top_text_size * 6, bottom_text1_paint);
        //起点使用text1的宽度
        canvas.drawText(bottom_txt2, width / 2 - bottomText1Width / 2 + (int) (top_text_size * 1.5), height / 2 + top_text_size * 6, bottom_text2_paint);
    }

    public void start(int progress) {
        final ValueAnimator valueAnimator = ValueAnimator.ofObject(new FloatEvaluator(), 0, progress);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                value = (Float) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        valueAnimator.setDuration(2000);
        valueAnimator.setInterpolator(new BounceInterpolator());
        valueAnimator.start();
    }

    public void setTopTop(String top_txt) {
        this.top_txt = top_txt;
        invalidate();
    }

    public void setBottomLeftTxt(String bottom_txt1) {
        this.bottom_txt1 = bottom_txt1;
        invalidate();
    }

    public void setBottomRightTxt(String bottom_txt2) {
        this.bottom_txt2 = bottom_txt2;
        invalidate();
    }

    private static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}


布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:orientation="vertical">

    <example.com.myping.HalfProgressView
        android:id="@+id/half_progress1"
        android:layout_width="30dp"
        android:layout_height="30dp" />

    <example.com.myping.HalfProgressView
        android:id="@+id/half_progress2"
        android:layout_width="60dp"
        android:layout_height="60dp" />

    <example.com.myping.HalfProgressView
        android:id="@+id/half_progress3"
        android:layout_width="90dp"
        android:layout_height="90dp" />

    <example.com.myping.HalfProgressView
        android:id="@+id/half_progress4"
        android:layout_width="120dp"
        android:layout_height="120dp" />

    <example.com.myping.HalfProgressView
        android:id="@+id/half_progress5"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>
public class TestActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);

        String top_txt = "当前进度";
        String bottom_txt1;
        String bottom_txt2 = "00%";
        HalfProgressView half_progress1 = (HalfProgressView) findViewById(R.id.half_progress1);
        half_progress1.setTopTop(top_txt);
        bottom_txt1 = "10.";
        half_progress1.setBottomLeftTxt(bottom_txt1);
        half_progress1.setBottomRightTxt(bottom_txt2);
        half_progress1.start(10);
        HalfProgressView half_progress2 = (HalfProgressView) findViewById(R.id.half_progress2);
        half_progress2.setTopTop(top_txt);
        bottom_txt1 = "40.";
        half_progress2.setBottomLeftTxt(bottom_txt1);
        half_progress2.setBottomRightTxt(bottom_txt2);
        half_progress2.start(40);
        HalfProgressView half_progress3 = (HalfProgressView) findViewById(R.id.half_progress3);
        half_progress3.setTopTop(top_txt);
        bottom_txt1 = "60.";
        half_progress3.setBottomLeftTxt(bottom_txt1);
        half_progress3.setBottomRightTxt(bottom_txt2);
        half_progress3.start(60);
        HalfProgressView half_progress4 = (HalfProgressView) findViewById(R.id.half_progress4);
        half_progress4.setTopTop(top_txt);
        bottom_txt1 = "80.";
        half_progress4.setBottomLeftTxt(bottom_txt1);
        half_progress4.setBottomRightTxt(bottom_txt2);
        half_progress4.start(80);
        HalfProgressView half_progress5 = (HalfProgressView) findViewById(R.id.half_progress5);
        half_progress5.setTopTop(top_txt);
        bottom_txt1 = "100.";
        half_progress5.setBottomLeftTxt(bottom_txt1);
        half_progress5.setBottomRightTxt(bottom_txt2);
        half_progress5.start(100);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值