自定義漂亮的進度條
阿新 • • 發佈:2019-01-24
最近在鴻洋的部落格上看到一個自定義的ProgressBar,在github上也看到了這種型別的Progress,地址為:https://github.com/daimajia/NumberProgressBar ,我第一反應就是,我自己能不能也寫一個呢,先上效果圖
ColorfulProgressBar.java
自定義的屬性attrs.xmlpackage com.cool.mylibrary.widget; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; import android.util.Log; import android.view.View; import com.cool.mylibrary.R; import com.cool.mylibrary.utils.UIUtils; /** * 漂亮的ProgressBar * Created by cool on 2016/9/14. */ public class ColorfulProgressBar extends View { private int mReachedColor;//進度條到達了的顏色 private int mUnReachedColor;//進度條未到達的顏色 private float mReachedHight;//進度條的到達的高度 private float mUnReachedHight;//進度條未到達的高度 private float mProgressTextOffset; private float mProgressTextSize; private Paint mReachPaint;//到達畫筆 private Paint mUnReachPaint;//未到達畫筆 private Paint mTextPaint;//文字畫筆 private int width; private int hight; private int mCurrentProgress; private int mTotalProgress = 100; private int textWith; public ColorfulProgressBar(Context context) { this(context, null); } public ColorfulProgressBar(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ColorfulProgressBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ColorfulProgressBar); mReachedColor = typedArray.getColor(R.styleable.ColorfulProgressBar_reachedColor, Color.parseColor("#DC143C")); mUnReachedColor = typedArray.getColor(R.styleable.ColorfulProgressBar_unReachedColor, Color.rgb(204, 204, 204)); mReachedHight = typedArray.getDimension(R.styleable.ColorfulProgressBar_reachedHight, UIUtils.dp2px(context, 3.5f)); mUnReachedHight = typedArray.getDimension(R.styleable.ColorfulProgressBar_unReachedHight, UIUtils.dp2px(context, 2.5f)); mProgressTextOffset = typedArray.getDimension(R.styleable.ColorfulProgressBar_progressTextOffset, UIUtils.dp2px(context, 3.0f)); mProgressTextSize = typedArray.getDimension(R.styleable.ColorfulProgressBar_progressTextSize, UIUtils.sp2px(context, 14.0f)); init(); } private void init() { mReachPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mReachPaint.setColor(mReachedColor); mReachPaint.setStrokeWidth(mReachedHight); mUnReachPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mUnReachPaint.setColor(mUnReachedColor); mUnReachPaint.setStrokeWidth(mUnReachedHight); mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mTextPaint.setColor(mReachedColor); mTextPaint.setTextSize(mProgressTextSize); } @Override protected void onDraw(Canvas canvas) { drawUnReachLine(canvas); drawText(canvas); drawReachLine(canvas); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int heightMode = MeasureSpec.getMode(heightMeasureSpec); if (heightMode != MeasureSpec.EXACTLY) { float textHeight = mTextPaint.descent() - mTextPaint.ascent(); int exceptHeight = (int) (getPaddingTop() + getPaddingBottom() + Math .max(Math.max(mReachedHight, mUnReachedHight), Math.abs(textHeight))); heightMeasureSpec = MeasureSpec.makeMeasureSpec(exceptHeight, MeasureSpec.EXACTLY); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } /** * 畫文字 * * @param canvas */ private void drawText(Canvas canvas) { String text = mCurrentProgress * 100 / mTotalProgress + "%"; Rect rect = new Rect(); mTextPaint.getTextBounds(text, 0, text.length(), rect); textWith = rect.right - rect.left; int x = (int) (((float) mCurrentProgress / mTotalProgress) * width + mProgressTextOffset); int y = hight/2 + (rect.bottom - rect.top)/2; if(x >= width-textWith){ x = width - textWith; } canvas.drawText(text,x,y,mTextPaint); } /** * 畫未到達的直線 * * @param canvas */ private void drawUnReachLine(Canvas canvas) { float startX = 0; float startY = hight/2; float endX = width; float endY = hight/2; canvas.drawLine(startX, startY, endX, endY, mUnReachPaint); } /** * 畫到達了的直線 * * @param canvas */ private void drawReachLine(Canvas canvas) { float startX = 0; float startY = hight/2; float endX = ((float) mCurrentProgress / mTotalProgress) * width; float endY = hight/2; if(endX >= width-textWith){ endX = width - textWith; } canvas.drawLine(startX, startY, endX, endY, mReachPaint); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { width = w; hight = h; } public void setProgress(int currentProgress) { mCurrentProgress = currentProgress; invalidate(); } public void setMax(int totalProgress) { mTotalProgress = totalProgress; } }
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="ColorfulProgressBar"> <attr name="reachedColor" format="color"/> <attr name="unReachedColor" format="color"/> <attr name="reachedHight" format="dimension"/> <attr name="unReachedHight" format="dimension"/> <attr name="progressTextOffset" format="dimension"/> <attr name="progressTextSize" format="dimension"/> </declare-styleable> </resources>
最後還有一個工具類UIUtils
package com.cool.mylibrary.utils; import android.content.Context; /** * Created by cool on 2016/9/14. */ public class UIUtils { /** * dp轉px * * @param context * @param dp * @return */ public static int dp2px(Context context, float dp) { float density = context.getResources().getDisplayMetrics().density; int px = (int) (dp * density + 0.5f); return px; } /** * px轉dp * * @param context * @param px * @return */ public static int px2dp(Context context, float px) { float density = context.getResources().getDisplayMetrics().density; int dp = (int) (px / density + 0.5f); return dp; } /** * sp轉px * @param context * @param sp * @return */ public static float sp2px(Context context, float sp) { final float scale = context.getResources().getDisplayMetrics().scaledDensity; return sp * scale; } }
使用:
佈局檔案中:
<com.cool.mylibrary.widget.ColorfulProgressBar
xmlns:cool="http://schemas.android.com/apk/res-auto"
android:id="@+id/ppb1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
cool:reachedColor="#FF1493" />
程式碼中:
prefectProgressBar = (ColorfulProgressBar) findViewById(R.id.ppb);
prefectProgressBar.setMax(100);
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 20; i++) {
final int finalI = i;
runOnUiThread(new Runnable() {
@Override
public void run() {
prefectProgressBar.setProgress(finalI);
}
});
SystemClock.sleep(40);
}
}
}).start();