Android自定义view之ProgressBar的实现

在学习自定义view之前我们必须先来了解一下attrs.xml这个文件,这个文件实际上定义了所有的控件的属性,就是我们在布局文件中设置的各类属性,因此在自定义控件属性的时候,创建一个attrs.xml文件来定义控件属性是十分重要的,下面我们开始进行项目的第一部分

一、attrs.xml文件的编写

首先在values文件下新建attrs.xml文件



<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!--属性的申明-->

    <attr name="progress_unreach_color" format="color"/>  //没有到达的时候进度条的颜色
    <attr name="progress_unreach_height" format="dimension"/>
    <attr name="progress_reach_color" format="color"/>   
    <attr name="progress_reach_height" format="dimension"/>
    <attr name="progress_text_color" format="color"/>   //<span style="font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px;">format的意思是说:这个textColor可以以两种方式设置,要么是关联一个值,要么<span style="white-space:pre">													</span>//是直接设置一个颜色的RGB值,这个不难理解,因为我们可以平时也这样做过。</span>
    <attr name="progress_text_size" format="dimension"/>
    <attr name="progress_text_offset" format="dimension"/>  //文本与两边的距离

    <!--属性的使用,不需要formet-->

    <declare-styleable name="HorizontalProgressBar">

        <attr name="progress_unreach_color" />
        <attr name="progress_unreach_height" />
        <attr name="progress_reach_color" />
        <attr name="progress_reach_height"/>
        <attr name="progress_text_color" />
        <attr name="progress_text_size" />
        <attr name="progress_text_offset" />  //文本与两边的距离


    </declare-styleable>

</resources>


接下来是自定义view class的编写以及view的绘制

package com.ricahrd.customprogressbar.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ProgressBar;

import com.ricahrd.customprogressbar.R;

/**
 * Created by jiangwei on 16/5/23.
 */
public class HorizontalProgressBar extends ProgressBar {

    private static final int DEFAULT_TEXT_SIZE = 10; //sp
    private static final int DEFAULT_TEXT_COLOR = 0xFFFC00D1;
    private static final int DEFAULT_COLOR_UNREACH = 0XFFD3D6DA;
    private static final int DEFAULT_HEIGHT_UNREACH = 2; //dp
    private static final int DEFAULT_COLOR_REACH = 0xFFFC00D1;
    private static final int DEFAULT_HEIGHT_REACH = 2; //dp
    private static final int DEFAULT_TEXT_OFFSET = 10; //dp

    //自定义所需成员变量
    private int mTextSize = sp2px(DEFAULT_TEXT_SIZE);
    private int mTextColor = DEFAULT_TEXT_COLOR;
    private int mUnReachColor = DEFAULT_COLOR_UNREACH;
    private int mUnReachHeight = dp2px(DEFAULT_HEIGHT_UNREACH);
    private int mReachColor = DEFAULT_COLOR_REACH;
    private int mReachHeight = dp2px(DEFAULT_HEIGHT_REACH);
    private int mTextOffSet = dp2px(DEFAULT_TEXT_OFFSET);

    private Paint mPaint = new Paint();
    private int mRealWidth;


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

    public HorizontalProgressBar(Context context, AttributeSet attrs) {
        super(context, attrs, 0);
    }

    public HorizontalProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        obtainStyleAttrs(attrs);
    }

    /**
     * 获取自定义属性
     *
     * @param attrs
     */

    private void obtainStyleAttrs(AttributeSet attrs) {
        TypedArray ta = getContext().obtainStyledAttributes(attrs,
                R.styleable.HorizontalProgressBar);

        mTextSize = (int) ta.getDimension(R.styleable.HorizontalProgressBar_progress_text_size
                , mTextSize);
        mTextColor = ta.getColor(R.styleable.HorizontalProgressBar_progress_text_color,
                mTextColor);
        mTextOffSet = (int) ta.getDimension(R.styleable.HorizontalProgressBar_progress_text_offset,
                mTextOffSet);
        mUnReachColor = ta.getColor(R.styleable.HorizontalProgressBar_progress_unreach_color,
                mUnReachColor);
        mUnReachHeight = (int) ta.getDimension(R.styleable.HorizontalProgressBar_progress_unreach_height,
                mUnReachHeight);
        mReachColor = ta.getColor(R.styleable.HorizontalProgressBar_progress_reach_color,
                mReachColor);
        mReachHeight = (int) ta.getDimension(R.styleable.HorizontalProgressBar_progress_reach_height,
                mReachHeight);


        ta.recycle();
        mPaint.setTextSize(mTextSize);


    }


    @Override
    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //宽度默认用户一定会给一个确定的值
//        int widthMod = MeasureSpec.getMode(widthMeasureSpec);
        int widthVal = MeasureSpec.getSize(widthMeasureSpec);
        int height = measureHeight(heightMeasureSpec);
        setMeasuredDimension(widthVal, height);

        mRealWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();

    }

    //测量高度
    private int measureHeight(int heightMeasureSpec) {

        int result = 0;
        int mode = MeasureSpec.getMode(heightMeasureSpec);
        int size = MeasureSpec.getSize(heightMeasureSpec);

        //用户给具体值
        if (mode == MeasureSpec.EXACTLY) {
            result = size;
        } else {
            int textheight = (int) (mPaint.descent() - mPaint.ascent());
            result = getPaddingBottom() + getPaddingTop() + Math.max(Math.max(mReachHeight, mUnReachHeight),
                    Math.abs(textheight));
            if (mode == MeasureSpec.AT_MOST) {
                result = Math.min(result, size);
            }


        }

        return result;
    }


    @Override
    protected synchronized void onDraw(Canvas canvas) {

        canvas.save();

        canvas.translate(getPaddingLeft(), getHeight() / 2);
        boolean noneedUnReach = false;

        String text = getProgress() + "%";
        //达到的长度百分比
        float radio = getProgress() * 1.0f / getMax();
        float progressX = radio * mRealWidth;

        int textwidth = (int) mPaint.measureText(text);
        if (progressX + textwidth > mRealWidth) {
            progressX = mRealWidth - textwidth;
            noneedUnReach = true;
        }

        float endx = progressX - mTextOffSet / 2;
        if (endx > 0) {
            mPaint.setColor(mReachColor);
            mPaint.setStrokeWidth(mReachHeight);
            canvas.drawLine(0, 0, endx, 0, mPaint);


        }

        //drawtext
        mPaint.setColor(mTextColor);
        mPaint.setTextSize(mTextSize);
        int y = (int) -(mPaint.descent() + mPaint.ascent()) / 2;
        canvas.drawText(text, progressX, y, mPaint);

        //draw unreachbar
        if (!noneedUnReach) {
            float start = progressX + mTextOffSet / 2 + textwidth;
            mPaint.setColor(mUnReachColor);
            mPaint.setStrokeWidth(mUnReachHeight);
            canvas.drawLine(start, 0, mRealWidth, 0, mPaint);

        }
        canvas.restore();
    }

    //dp转换成int的方法
    public int dp2px(int dpVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal,
                getResources().getDisplayMetrics());

    }

    //sp转换成int的方法
    public int sp2px(int spVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spVal,
                getResources().getDisplayMetrics());

    }


}



布局文件activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:hyman="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"

        >

        <com.ricahrd.customprogressbar.view.HorizontalProgressBar

            android:id="@+id/progress_01"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:padding="5dp"
            hyman:progress_reach_color="#ffff0000"
            hyman:progress_text_color="#ffff0000"
            hyman:progress_unreach_color="#44ff0000"
            android:progress="40" />

       

    </LinearLayout>


</ScrollView>

实现效果:



这就是一个简单的自定义水平进度条工程,欢迎大家与我交流~~~

猜你喜欢

转载自blog.csdn.net/qq_17475155/article/details/51501206