1. 程式人生 > >Android 自定義View--ProgressBar篇(一)

Android 自定義View--ProgressBar篇(一)

1、概述

1.1 目的 :

在我們的日常開發中,有很多Android UI介面上有一些特殊或者特別的控制元件與介面,是Android自帶的控制元件所不能滿足的,需要我們自己定製一些適合的控制元件來完成。

1.2 Android自定義View步驟 :

  1. 自定義屬性;
  2. 選擇和設定構造方法;
  3. 重寫onMeasure()方法;
  4. 重寫onDraw()方法;
  5. 重寫onLayout()方法;
  6. 重寫其他事件的方法(滑動監聽等)。

2、程式碼實現

2.1 自定義屬性:

我們通常將自定義屬性定義在/values/attr.xml檔案中(attr.xml檔案需要自己建立)。

<declare-styleable name="UpdataAPPProgressBar">
        <attr name="updataAPPReachedBarColor" format="color" />
        <attr name="updataAPPUnreachedBarColor" format="color" />
        <attr name="updataAPPTextColor" format="color" />
        <attr name="updataAPPBarHeight" format="dimension"/>
        <attr name="updataAPPMax" format="integer" />
        <attr name="updataAPPProgress" format="integer" />
        <attr name="updataAPPSuffix" format="string" />
        <attr name="updataAPPPrefix" format="string" />
        <attr name="updataAPPTextVisibility" format="boolean"/>
    </declare-styleable>

2.2 實現方法含義

1、在OnMeasure()方法中,測量自定義控制元件的大小,使自定義控制元件能夠自適應佈局各種各樣的需求。
2、在OnDraw()方法中,利用哼哈二將(Canvas與Paint)來繪製要顯示的內容。
3、在OnLayout()方法中來確定控制元件顯示位置。
4、在OnTouchEvent()方法處理控制元件的觸控事件。、

在這裡插入圖片描述

2.3 繼承View實現程式碼

package com.fly.myview.progressbar;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;

import com.fly.myview.R;

import java.text.DecimalFormat;
import java.util.HashMap;

/**
 * <pre>
 *           .----.
 *        _.'__    `.
 *    .--(Q)(OK)---/$\
 *  .' @          /$$$\
 *  :         ,   $$$$$
 *   `-..__.-' _.-\$$/
 *         `;_:    `"'
 *       .'"""""`.
 *      /,  FLY  ,\
 *     //         \\
 *     `-._______.-'
 *     ___`. | .'___
 *    (______|______)
 * </pre>
 * 包    名 : com.fly.myview.progressbar
 * 作    者 : FLY
 * 建立時間 : 2018/9/6
 * 描述: 更新下載的進度條
 */

public class UpdataAPPProgressBar extends View {

    /**
     * 進度條最大值
     */
    private float mMax = 100;

    /**
     * 進度條當前進度值
     */
    private float mProgress = 0;

    /**
     * 預設已完成顏色
     */
    private final int DEFAULT_FINISHED_COLOR = getResources().getColor(R.color.arc_progress_finished_color);

    /**
     * 預設未完成顏色
     */
    private final int DEFAULT_UNFINISHED_COLOR = getResources().getColor(R.color.arc_progress_unfinished_color);

    /**
     * 已完成進度顏色
     */
    private int mReachedBarColor;

    /**
     * 未完成進度顏色
     */
    private int mUnreachedBarColor;

    /**
     * 進度條高度
     */
    private float mBarHeight;

    /**
     * the progress text color.
     */
    private int mTextColor;

    /**
     * 字尾
     */
    private String mSuffix = "%";

    /**
     * 字首
     */
    private String mPrefix = "";

    /**
     * 未完成進度條所在矩形區域
     */
    private RectF mUnreachedRectF = new RectF(0, 0, 0, 0);
    /**
     * 已完成進度條所在矩形區域
     */
    private RectF mReachedRectF = new RectF(0, 0, 0, 0);

    /**
     * 畫筆
     */
    private Paint mPaint;

    private boolean mTextVisibility;


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

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

    public UpdataAPPProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttrs(context, attrs);
        initPainters();
    }

    private void initAttrs(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.UpdataAPPProgressBar);
        mMax = typedArray.getInteger(R.styleable.UpdataAPPProgressBar_updataAPPMax, (int) mMax);
        mProgress = typedArray.getInteger(R.styleable.UpdataAPPProgressBar_updataAPPProgress, (int) mProgress);
        mReachedBarColor = typedArray.getColor(R.styleable.UpdataAPPProgressBar_updataAPPReachedBarColor, DEFAULT_FINISHED_COLOR);
        mUnreachedBarColor = typedArray.getColor(R.styleable.UpdataAPPProgressBar_updataAPPUnreachedBarColor, DEFAULT_UNFINISHED_COLOR);
        mTextColor = typedArray.getColor(R.styleable.UpdataAPPProgressBar_updataAPPTextColor, DEFAULT_UNFINISHED_COLOR);
        mSuffix = TextUtils.isEmpty(typedArray.getString(R.styleable.UpdataAPPProgressBar_updataAPPSuffix)) ? mSuffix : typedArray.getString(R.styleable.UpdataAPPProgressBar_updataAPPSuffix);
        mPrefix = TextUtils.isEmpty(typedArray.getString(R.styleable.UpdataAPPProgressBar_updataAPPPrefix)) ? mPrefix : typedArray.getString(R.styleable.UpdataAPPProgressBar_updataAPPPrefix);
        mBarHeight = typedArray.getDimension(R.styleable.UpdataAPPProgressBar_updataAPPBarHeight, dp2px(2f));
        mTextVisibility = typedArray.getBoolean(R.styleable.UpdataAPPProgressBar_updataAPPTextVisibility, true);
        typedArray.recycle();
    }

    private void initPainters() {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);//抗鋸齒
        mPaint.setAntiAlias(true);//防抖動
        mPaint.setStrokeCap(Paint.Cap.ROUND);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        calculateDrawRectFWithoutProgressText();
        mPaint.setColor(mUnreachedBarColor);
        canvas.drawRoundRect(mUnreachedRectF, mBarHeight / 2, mBarHeight / 2, mPaint);

        mPaint.setColor(mReachedBarColor);
        canvas.drawRoundRect(mReachedRectF, mBarHeight / 2, mBarHeight / 2, mPaint);


        mPaint.setColor(mTextColor);
        mPaint.setTextSize(mBarHeight * 0.6f);
        String mCurrentDrawText = new DecimalFormat("#").format(getProgress() * 100 / getMax());
        mCurrentDrawText = mPrefix + mCurrentDrawText + mSuffix;
        float mDrawTextWidth = mPaint.measureText(mCurrentDrawText);
        if (mTextVisibility && getProgress() > 0 && mReachedRectF.right >mDrawTextWidth) {
            canvas.drawText(mCurrentDrawText, mReachedRectF.right - mDrawTextWidth - mBarHeight * 0.4f, (int) ((getHeight() / 2.0f) - ((mPaint.descent() + mPaint.ascent()) / 2.0f)), mPaint);
        }


    }

    private void calculateDrawRectFWithoutProgressText() {
        mReachedRectF.left = getPaddingLeft();
        mReachedRectF.top = getHeight() / 2.0f - mBarHeight / 2.0f;
        mReachedRectF.right = (getWidth() - getPaddingLeft() - getPaddingRight()) / (getMax() * 1.0f) * getProgress() + getPaddingLeft();
        mReachedRectF.bottom = getHeight() / 2.0f + mBarHeight / 2.0f;

        mUnreachedRectF.left = getPaddingLeft();
        mUnreachedRectF.top = getHeight() / 2.0f + -mBarHeight / 2.0f;
        mUnreachedRectF.right = getWidth() - getPaddingRight();
        mUnreachedRectF.bottom = getHeight() / 2.0f + mBarHeight / 2.0f;
    }

    public float getMax() {
        return mMax;
    }

    public float getProgress() {
        return mProgress;
    }

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

    public void setProgress(float progress) {
        this.mProgress = checkProgress(progress);
        invalidate();
    }


    private float checkProgress(float progress) {
        if (progress < 0) return 0;
        return progress > mMax ? mMax : progress;
    }

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


3、使用

 <com.fly.myview.progressbar.UpdataAPPProgressBar
        android:id="@+id/updata"
        android:layout_width="match_parent"
        android:layout_height="20dp"
        app:updataAPPBarHeight="20dp"
        android:padding="@dimen/dp_10"
        app:updataAPPMax="100"
        app:updataAPPProgress="0"
        app:updataAPPReachedBarColor="#FF6770"
        app:updataAPPUnreachedBarColor="#EBEBEB"
        app:updataAPPTextColor="@color/color_white" />

4.效果

在這裡插入圖片描述
在這裡插入圖片描述

希望對各位朋友有幫助,謝謝!!!!