Android 自定義View--ProgressBar篇(一)
阿新 • • 發佈:2019-01-24
1、概述
1.1 目的 :
在我們的日常開發中,有很多Android UI介面上有一些特殊或者特別的控制元件與介面,是Android自帶的控制元件所不能滿足的,需要我們自己定製一些適合的控制元件來完成。
1.2 Android自定義View步驟 :
- 自定義屬性;
- 選擇和設定構造方法;
- 重寫onMeasure()方法;
- 重寫onDraw()方法;
- 重寫onLayout()方法;
- 重寫其他事件的方法(滑動監聽等)。
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.效果
希望對各位朋友有幫助,謝謝!!!!