android 自定义view实现仿QQ运动步数进度效果

最近公司在策划一个新的项目,原型还没出来,再说这公司人都要走没了,估计又要找工作了,所以必须要学习,争取每个写个关于自定义view方面的,这样几个月积累下来,也能学习到东西,今天就带来简单的效果,就是仿QQ运动步数的进度条效果.在这就不分析了,直接贴代码,

自定义属性:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="QQMovementView">
        <attr name="defaultCircleColor" format="color|reference"></attr>
        <attr name="ProgressColor" format="color|reference"></attr>
        <attr name="CustomTextColor" format="color|reference"></attr>
        <attr name="CustomTextSize" format="dimension|reference"></attr>
        <attr name="BorderWidth" format="integer|reference"></attr>
        <attr name="ProgressMax" format="integer|reference"></attr>
        <attr name="currentProgress" format="integer|reference"></attr>
        <attr name="CustomStartAngle" format="integer|reference"></attr>
        <attr name="CustomSweepAngle" format="integer|reference"></attr>
    </declare-styleable>
</resources>

自定义View

package com.day01;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
/**
 * Created by zhouguizhijxhz on 2018/5/24.
 */
public class QQMovementView extends View {
    private static final String TAG = "QQMovementView";
    private Paint progressPaint;
    private Paint textPaint;
    private Paint circlePaint;
    private int defaultCircleColor = Color.parseColor("#FF82AB");
    private int defaultTextColor = Color.parseColor("#ff3f3f");
    private int defaultTextSize = 24;
    private int borderWidth = 12;
    private int progressColor = Color.parseColor("#FFA07A");
    private int max = 100;
    private int currentProgress = 10;
    private int startAngle = 135;
    private int sweepAngle = 270;

    public QQMovementView(Context context) {
        this(context, null);
    }

    public QQMovementView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public QQMovementView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttrs(context, attrs);
        initTextPaint(context);
        initCirclePaint();
        initProgressPaint();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = measureWidth(widthMeasureSpec);
        int height = measureHeight(heightMeasureSpec);
        setMeasuredDimension(Math.min(width, height), Math.min(width, height));
    }

    private int measureHeight(int heightMeasureSpec) {
        int mode = MeasureSpec.getMode(heightMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        if (mode == MeasureSpec.AT_MOST) {
            height = 360;
        }
        return height;
    }

    private int measureWidth(int widthMeasureSpec) {
        int mode = MeasureSpec.getMode(widthMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        if (mode == MeasureSpec.AT_MOST) {
            width = 360;
        }
        return width;
    }

    private void initProgressPaint() {
        progressPaint = new Paint();
        progressPaint.setColor(progressColor);
        progressPaint.setStrokeWidth(borderWidth);
        progressPaint.setStyle(Paint.Style.STROKE);
        progressPaint.setStrokeCap(Paint.Cap.ROUND);
        progressPaint.setAntiAlias(true);
    }

    private void initCirclePaint() {
        circlePaint = new Paint();
        circlePaint.setColor(defaultCircleColor);
        circlePaint.setStrokeWidth(borderWidth);
        circlePaint.setStyle(Paint.Style.STROKE);
        circlePaint.setStrokeCap(Paint.Cap.ROUND);
        circlePaint.setAntiAlias(true);
    }

    private void initTextPaint(Context context) {
        textPaint = new Paint();
        textPaint.setColor(defaultTextColor);
        textPaint.setTextSize(sp2px(context,defaultTextSize));
    }

    private void initAttrs(Context context, AttributeSet attrs) {
        if (null == context || null == attrs) {
            return;
        }
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.QQMovementView);
        defaultCircleColor = typedArray.getColor(R.styleable.QQMovementView_defaultCircleColor, defaultCircleColor);
        defaultTextColor = typedArray.getColor(R.styleable.QQMovementView_CustomTextColor, defaultTextColor);
        defaultTextSize = typedArray.getDimensionPixelSize(R.styleable.QQMovementView_CustomTextSize, defaultTextSize);
        progressColor = typedArray.getColor(R.styleable.QQMovementView_ProgressColor, progressColor);
        borderWidth = typedArray.getInteger(R.styleable.QQMovementView_BorderWidth, borderWidth);
        max = typedArray.getInteger(R.styleable.QQMovementView_ProgressMax,max);
        currentProgress = typedArray.getInteger(R.styleable.QQMovementView_currentProgress,currentProgress);
        startAngle = typedArray.getInteger(R.styleable.QQMovementView_CustomStartAngle,startAngle);
        sweepAngle = typedArray.getInteger(R.styleable.QQMovementView_CustomSweepAngle,sweepAngle);
        Log.e(TAG,"max--->"+max);
        Log.e(TAG,"currentProgress--->"+currentProgress);
        typedArray.recycle();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawArc(canvas);
        drawProgressArc(canvas);
        drawProgressText(canvas);
    }

    private void drawProgressText(Canvas canvas) {
        if (null == canvas) {
            return;
        }
        String strPercent = String.valueOf(currentProgress);
        Paint.FontMetricsInt fm = textPaint.getFontMetricsInt();
        canvas.drawText(strPercent, getWidth() / 2 - textPaint.measureText(strPercent) / 2,
                getHeight() / 2 - (fm.bottom + fm.top) / 2, textPaint);
    }

    private void drawProgressArc(Canvas canvas) {
        if (null == canvas) {
            return;
        }
        if (max == 0) {
            return;
        }
        if (currentProgress == 0) {
            return;
        }
        RectF rectF = new RectF(borderWidth / 2, borderWidth / 2, getMeasuredWidth() - borderWidth / 2, getMeasuredHeight() - borderWidth / 2);
        float percent = (float) currentProgress / max;
        Log.e(TAG,"percent------->"+percent);
        canvas.drawArc(rectF, startAngle, sweepAngle * percent, false, progressPaint);
    }

    private void drawArc(Canvas canvas) {
        if (null == canvas) {
            return;
        }
        RectF rectF = new RectF(borderWidth / 2, borderWidth / 2, getMeasuredWidth() - borderWidth / 2, getMeasuredHeight() - borderWidth / 2);
        canvas.drawArc(rectF, startAngle, sweepAngle, false, circlePaint);
    }

    public static int sp2px(Context context, float spValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }

    public void setMax(int max) {
        this.max = max;
    }

    public void setCurrentProgress(int currentProgress) {
        this.currentProgress = currentProgress;
    }
}

布局:

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <com.day01.QQMovementView
        android:layout_width="240dp"
        android:layout_height="240dp"
        android:layout_centerHorizontal="true"
        android:layout_marginRight="60dp"
        android:layout_marginTop="60dp"
        app:currentProgress="30"
        app:ProgressMax="200"
         />
</RelativeLayout>

效果:


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值