android 自定义view实现应用宝进度条下载效果

这个有好多种做法,我就讲二种方法,第一种方法就是自定义一个view,通过canvas画线就可以,只要把paint的width改成view的高度就行:

package com.day01;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import java.math.BigDecimal;

/**
 * Created by zhouguizhijxhz on 2018/5/24.
 */
public class CustomProgress extends View implements View.OnClickListener {
    private Paint defaultPaint;
    private Paint rollPaint;
    private float percent = 0.0f;
    private Paint textPaint;
    private Handler mHandler = new Handler();
    private MyRunnable myRunnable;
    public CustomProgress(Context context) {
        this(context, null);
    }

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

    public CustomProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        myRunnable = new MyRunnable();
        initPaint();
        setOnClickListener(this);
    }

    private void initPaint() {
        defaultPaint = new Paint();
        defaultPaint.setColor(Color.parseColor("#999999"));
        defaultPaint.setStyle(Paint.Style.STROKE);


        rollPaint = new Paint();
        rollPaint.setColor(Color.parseColor("#1C86EE"));
        rollPaint.setStyle(Paint.Style.STROKE);

        textPaint = new Paint();
        textPaint.setColor(Color.parseColor("#202020"));
        textPaint.setTextSize(sp2px(15));
    }

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

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

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

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawDefaultProgressButton(canvas);
        drawRollProgressButton(canvas);
        drawText(canvas);
    }

    private void drawText(Canvas canvas) {
        if (null == canvas) {
            return;
        }
        if (percent == 0) {
            String text = "下载";
            Paint.FontMetricsInt fm = textPaint.getFontMetricsInt();
            canvas.drawText(text, getWidth() / 2 - textPaint.measureText(text) / 2,
                    getHeight() / 2 - (fm.bottom + fm.top) / 2, textPaint);
        } else if(percent>0) {
            Log.e("percent","percent------------>"+percent);
            String text = percent*100+ "%";
            Paint.FontMetricsInt fm = textPaint.getFontMetricsInt();
            canvas.drawText(text, getWidth() / 2 - textPaint.measureText(text) / 2,
                    getHeight() / 2 - (fm.bottom + fm.top) / 2, textPaint);
            mHandler.postDelayed(myRunnable,500);
        }
    }

    private void drawRollProgressButton(Canvas canvas) {
        if (null == canvas) {
            return;
        }
        rollPaint.setStrokeWidth(dp2px(getMeasuredHeight()));
        canvas.drawLine(0, 0,  percent*getMeasuredWidth(), 0, rollPaint);
    }

    private void drawDefaultProgressButton(Canvas canvas) {
        if (null == canvas) {
            return;
        }
        defaultPaint.setStrokeWidth(dp2px(getMeasuredHeight()));
        canvas.drawLine(0, 0, getMeasuredWidth(), 0, defaultPaint);
    }

    private int dp2px(float dpValue) {
        float scale = getContext().getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * px转换成dp
     */
    private int px2dp(float pxValue) {
        float scale = getContext().getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

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

    @Override
    public void onClick(View v) {
        percent+=0.1f;
        invalidate();
    }
    class MyRunnable implements Runnable{
        @Override
        public void run() {
            if(percent>=1.0){
                return;
            }
            BigDecimal bigDecimal = new BigDecimal(Float.toString(percent));
            BigDecimal bigDecimal1 = new BigDecimal(Float.toString(0.1f));
            percent=bigDecimal.add(bigDecimal1).floatValue();
            postInvalidate();
        }
    }
}

第二种做法:

这个就是绘制矩形,关键是要用到canvas的clipRect()方法,也就是画布裁剪:

package com.day01;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import java.math.BigDecimal;
/**
 * Created by zhouguizhijxhz on 2018/5/24.
 */
public class CustomProgress extends View implements View.OnClickListener {
    private Paint defaultPaint;
    private Paint rollPaint;
    private float percent = 0.0f;
    private Paint textPaint;
    private Handler mHandler = new Handler();
    private MyRunnable myRunnable;
    public CustomProgress(Context context) {
        this(context, null);
    }

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

    public CustomProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        myRunnable = new MyRunnable();
        initPaint();
        setOnClickListener(this);
    }

    private void initPaint() {
        defaultPaint = new Paint();
        defaultPaint.setColor(Color.parseColor("#999999"));
        defaultPaint.setStyle(Paint.Style.FILL);


        rollPaint = new Paint();
        rollPaint.setColor(Color.parseColor("#1C86EE"));
        rollPaint.setStyle(Paint.Style.FILL);

        textPaint = new Paint();
        textPaint.setColor(Color.parseColor("#202020"));
        textPaint.setTextSize(sp2px(15));
    }

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

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

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

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawDefaultProgressButton(canvas);
        drawRollProgressButton(canvas);
        drawText(canvas);
    }

    private void drawText(Canvas canvas) {
        if (null == canvas) {
            return;
        }
        if (percent == 0) {
            String text = "下载";
            Paint.FontMetricsInt fm = textPaint.getFontMetricsInt();
            canvas.drawText(text, getWidth() / 2 - textPaint.measureText(text) / 2,
                    getHeight() / 2 - (fm.bottom + fm.top) / 2, textPaint);
        } else if(percent>0) {
            BigDecimal re1=new BigDecimal(Float.toString(percent));
            BigDecimal re2=new BigDecimal(Float.toString(100.0f));
            String text = re1.multiply(re2).floatValue()+"%";
            Paint.FontMetricsInt fm = textPaint.getFontMetricsInt();
            canvas.drawText(text, getWidth() / 2 - textPaint.measureText(text) / 2,
                    getHeight() / 2 - (fm.bottom + fm.top) / 2, textPaint);
            mHandler.postDelayed(myRunnable,500);
        }
    }

    private void drawRollProgressButton(Canvas canvas) {
        if (null == canvas) {
            return;
        }
        canvas.save();
        Rect rect = new Rect(0, 0, (int) (percent*getMeasuredWidth()), getMeasuredHeight());
        canvas.clipRect(rect);
        canvas.drawRect(rect,rollPaint);
        canvas.restore();
    }

    private void drawDefaultProgressButton(Canvas canvas) {
        if (null == canvas) {
            return;
        }
        canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),defaultPaint);
    }

    private int dp2px(float dpValue) {
        float scale = getContext().getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * px转换成dp
     */
    private int px2dp(float pxValue) {
        float scale = getContext().getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

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

    @Override
    public void onClick(View v) {
        percent+=0.1f;
        invalidate();
    }
    class MyRunnable implements Runnable{
        @Override
        public void run() {
            if(percent>=1.0){
                return;
            }
            BigDecimal bigDecimal = new BigDecimal(Float.toString(percent));
            BigDecimal bigDecimal1 = new BigDecimal(Float.toString(0.1f));
            percent=bigDecimal.add(bigDecimal1).floatValue();
            postInvalidate();
        }
    }
}

效果:


如果想要二边有圆形的,就使用第一种方式,而且paint上使用setStrokeCap(Paint.Cap.ROUND)这个方法加上线冒,如果是绘制矩形的这个方法是无效的.

猜你喜欢

转载自blog.csdn.net/coderinchina/article/details/80443594