1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Android仿MIUI手機(jī)管家分?jǐn)?shù)值進(jìn)度條

        共 13108字,需瀏覽 27分鐘

         ·

        2022-03-01 18:42

        效果圖:



        這個(gè)也是一個(gè)進(jìn)度條,之前在MIUI9上的手機(jī)管家上看到,效果是一段弧度,中間一個(gè)百分比文字。


        完整代碼


        • 自定義屬性

                                                                                                                                                    


        • Java代碼

        public class CircleProgressWithTextView extends View {    /**     * 默認(rèn)值     */    /**     * 默認(rèn)的當(dāng)前進(jìn)度,默認(rèn)為0     */    private static final int DEFAULT_PROGRESS = 0;    /**     * 默認(rèn)的最大值,默認(rèn)為100     */    private static final int DEFAULT_MAX = 100;    /**     * 默認(rèn)進(jìn)度圓弧顏色     */    private final int DEFAULT_CIRCLE_COLOR = Color.parseColor("#0AA4A2");    /**     * 圓弧顏色     */    private final int DEFAULT_REMAIN_CIRCLE_COLOR = Color.parseColor("#EFEFF0");    /**     * 默認(rèn)背景顏色     */    private final int DEFAULT_BG_COLOR = Color.parseColor("#00000000");    /**     * 默認(rèn)文字顏色     */    private final int DEFAULT_TEXT_COLOR = Color.parseColor("#0AA4A2");    /**     * 是否顯示進(jìn)度百分比文字     */    private static final boolean DEFAULT_TEXT_ENABLE = true;    /**     * 繪制相關(guān)     */    private RectF mRect;    private Paint mCirclePaint;    private Paint mTextPaint;    private Paint mPercentPaint;    /**     * 畫(huà)筆顏色     */    private int mCircleColor;    private int mRemainCircleColor;    private int mTextColor;    private int mBgColor;    /**     * 圓弧寬度     */    private float mCircleBorderWidth;    /**     * View相關(guān)尺寸     */    private int mWidth;    private int mHeight;    /**     * 外圓半徑     */    private float mRadius;    /**     * 當(dāng)前進(jìn)度     */    private float mProgress;    /**     * 進(jìn)度最大值     */    private int mMax;    /**     * 是否顯示百分比文字     */    private boolean mEnableText;    /**     * 弧線(xiàn)的開(kāi)始角度,默認(rèn)是0,是水平的,我們要從上面開(kāi)始畫(huà)     */    private float mStartAngle = -90f;    /**     * 中心點(diǎn)X、Y坐標(biāo)     */    private int mCenterX;    private int mCenterY;    /**     * 進(jìn)度條進(jìn)度     */    private ValueAnimator mProgressAnimator;    private OnProgressUpdateListener mProgressUpdateListener;
        public CircleProgressWithTextView(Context context) { super(context); init(null); }
        public CircleProgressWithTextView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(attrs); }
        public CircleProgressWithTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(attrs); }
        /** * 初始化自定義屬性 */ private void initAttributeVar(AttributeSet attrs) { //默認(rèn)圓弧寬度 int defaultCircleBorderWidth = dip2px(getContext(), 5f); if (attrs != null) { TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.CircleProgressWithTextView); mProgress = array.getInt(R.styleable.CircleProgressWithTextView_cpt_progress, DEFAULT_PROGRESS); mMax = array.getInt(R.styleable.CircleProgressWithTextView_cpt_max, DEFAULT_MAX); //Xml設(shè)置的進(jìn)度圓弧顏色 mCircleColor = array.getColor(R.styleable.CircleProgressWithTextView_cpt_circle_color, DEFAULT_CIRCLE_COLOR); //Xml設(shè)置的圓弧顏色 mRemainCircleColor = array.getColor(R.styleable.CircleProgressWithTextView_cpt_remain_circle_color, DEFAULT_REMAIN_CIRCLE_COLOR); //文字顏色 mTextColor = array.getColor(R.styleable.CircleProgressWithTextView_cpt_text_color, DEFAULT_CIRCLE_COLOR); //讀取設(shè)置的圓弧輪廓寬度,讀取dimension mCircleBorderWidth = array.getDimensionPixelSize(R.styleable.CircleProgressWithTextView_cpt_remain_circle_border_width, defaultCircleBorderWidth); //是否顯示進(jìn)度百分比文字 mEnableText = array.getBoolean(R.styleable.CircleProgressWithTextView_cpt_text_enable, DEFAULT_TEXT_ENABLE); //背景顏色 mBgColor = array.getColor(R.styleable.CircleProgressWithTextView_cpt_bg_color, DEFAULT_BG_COLOR); array.recycle(); } else { //沒(méi)有在Xml中設(shè)置屬性,使用默認(rèn)屬性 mProgress = DEFAULT_PROGRESS; mMax = DEFAULT_MAX; mCircleColor = DEFAULT_CIRCLE_COLOR; mRemainCircleColor = DEFAULT_REMAIN_CIRCLE_COLOR; mTextColor = DEFAULT_TEXT_COLOR; mCircleBorderWidth = defaultCircleBorderWidth; mEnableText = DEFAULT_TEXT_ENABLE; } }
        private void init(AttributeSet attrs) { initAttributeVar(attrs); //外圓畫(huà)筆 mCirclePaint = new Paint(); mCirclePaint.setColor(mCircleColor); mCirclePaint.setStrokeWidth(mCircleBorderWidth); mCirclePaint.setStyle(Paint.Style.STROKE); //設(shè)置筆觸為圓角 mCirclePaint.setStrokeCap(Paint.Cap.ROUND); mCirclePaint.setAntiAlias(true); //文字畫(huà)筆 mTextPaint = new Paint(); mTextPaint.setColor(mTextColor); mTextPaint.setStrokeWidth(dip2px(getContext(), 1f)); mTextPaint.setStyle(Paint.Style.FILL); mTextPaint.setTextSize(sp2px(getContext(), 17f)); mTextPaint.setAntiAlias(true); //百分比畫(huà)筆 mPercentPaint = new Paint(); mPercentPaint.setColor(mTextColor); mPercentPaint.setStrokeWidth(dip2px(getContext(), 1f)); mPercentPaint.setStyle(Paint.Style.FILL); mPercentPaint.setTextSize(sp2px(getContext(), 13f)); mPercentPaint.setAntiAlias(true); }
        @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); //控件的總寬高 mWidth = w; mHeight = h; //取出padding值 int paddingLeft = getPaddingLeft(); int paddingRight = getPaddingRight(); int paddingTop = getPaddingTop(); int paddingBottom = getPaddingBottom(); //繪制范圍 mRect = new RectF(); mRect.left = (float) paddingLeft; mRect.top = (float) paddingTop; mRect.right = (float) mWidth - paddingRight; mRect.bottom = (float) mHeight - paddingBottom; //計(jì)算直徑和半徑 float diameter = (Math.min(mWidth, mHeight)) - paddingLeft - paddingRight; mRadius = (float) ((diameter / 2) * 0.98); //計(jì)算圓心的坐標(biāo) mCenterX = mWidth / 2; mCenterY = mHeight / 2; }
        @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(measureSpec(widthMeasureSpec), measureSpec(heightMeasureSpec)); }
        private int measureSpec(int measureSpec) { int result; int mode = MeasureSpec.getMode(measureSpec); int size = MeasureSpec.getSize(measureSpec); //默認(rèn)大小 int defaultSize = dip2px(getContext(), 55f); //指定寬高則直接返回 if (mode == MeasureSpec.EXACTLY) { result = size; } else if (mode == MeasureSpec.AT_MOST) { //wrap_content的情況 result = Math.min(defaultSize, size); } else {//未指定,則使用默認(rèn)的大小 result = defaultSize; } return result; }
        @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.scale(0.93f, 0.93f, mCenterX, mCenterY); drawBg(canvas); float curProgress = getProgress(); //畫(huà)圓弧 drawCircle(canvas, curProgress); if (mEnableText) { //畫(huà)文字 String progressText = String.valueOf((int) curProgress); drawProgressText(canvas, progressText); } }
        /** * 畫(huà)背景 */ private void drawBg(Canvas canvas) { canvas.drawColor(mBgColor); }
        /** * 畫(huà)圓弧 */ private void drawCircle(Canvas canvas, float curProgress) { mCirclePaint.setColor(mRemainCircleColor); canvas.drawCircle(mCenterX, mCenterY, mRadius, mCirclePaint); //繪制當(dāng)前進(jìn)度的弧線(xiàn) mCirclePaint.setColor(mCircleColor); float angle = 360 * (curProgress * 1.0f / getMax()); canvas.drawArc(mRect, mStartAngle, angle, false, mCirclePaint); //繪制剩下的度數(shù)的弧線(xiàn) //float remainAngle = 360f - angle; //mCirclePaint.setColor(mRemainCircleColor); //canvas.drawArc(mRect, mStartAngle + angle, remainAngle, false, mCirclePaint); }
        /** * 畫(huà)進(jìn)度文字 */ private void drawProgressText(Canvas canvas, String progressText) { Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics(); float baseLine = -(fontMetrics.ascent + fontMetrics.descent) / 2; float textWidth = mTextPaint.measureText(progressText); float startX = mCenterX - (textWidth / 2); float endY = mCenterY + baseLine; canvas.drawText(progressText, startX, endY, mTextPaint); //畫(huà)百分比 String percentText = "%"; //計(jì)算百分比文字的起始X坐標(biāo) float percentStartX = 0; if (progressText.length() == 1) { percentStartX = mCenterX + dip2px(getContext(), 5f); } else if (progressText.length() == 2) { percentStartX = mCenterX + dip2px(getContext(), 10f); } //百分比文字Y坐標(biāo),中心點(diǎn)Y坐標(biāo),和數(shù)值文字的Y坐標(biāo)一樣 float percentEndY = mCenterY + baseLine; canvas.drawText(percentText, percentStartX, percentEndY, mPercentPaint); }
        /** * 指定時(shí)間,開(kāi)始進(jìn)度 * * @param preProgress 之前的進(jìn)度 * @param duration 執(zhí)行時(shí)間 */ public void startProgressByTime(int preProgress, long duration) { if (mProgressAnimator == null) { mProgressAnimator = ValueAnimator.ofInt(preProgress, mMax); } mProgressAnimator.setInterpolator(new LinearInterpolator()); mProgressAnimator.setDuration(duration); mProgressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Integer cValue = (Integer) animation.getAnimatedValue(); setProgress(cValue); if (mProgressUpdateListener != null) { mProgressUpdateListener.onProgressUpdate(cValue); } } }); mProgressAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); if (mProgressUpdateListener != null) { mProgressUpdateListener.onStart(); } }
        @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); //結(jié)束,設(shè)置回0 setProgress(0); if (mProgressUpdateListener != null) { mProgressUpdateListener.onEnd(); } } }); mProgressAnimator.start(); }
        /** * 進(jìn)度更新監(jiān)聽(tīng) */ public interface OnProgressUpdateListener { void onStart();
        /** * 進(jìn)度更新 * * @param curProgress 當(dāng)前進(jìn)度 */ void onProgressUpdate(int curProgress);
        void onEnd(); }
        public static class OnProgressUpdateAdapter implements OnProgressUpdateListener {
        @Override public void onStart() { }
        @Override public void onProgressUpdate(int curProgress) { }
        @Override public void onEnd() { } }
        public void setOnProgressUpdateListener(OnProgressUpdateListener progressUpdateListener) { mProgressUpdateListener = progressUpdateListener; }
        public float getProgress() { return mProgress; }
        public void setProgress(float mProgress) { this.mProgress = mProgress; postInvalidate(); }
        public float getMax() { return mMax; }
        public void setMax(int max) { this.mMax = max; postInvalidate(); }
        public static int dip2px(Context context, float dipValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dipValue * scale + 0.5f); }
        public static int px2dp(Context context, float pxValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); }
        private int sp2px(Context context, float spVal) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spVal, context.getResources().getDisplayMetrics()); }}


        示例代碼


        • Xml布局

        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.hzh.circle.progress.sample.MainActivity">
        <com.hzh.circle.progress.sample.widget.CircleProgressWithTextView android:id="@+id/circleProgress" android:layout_width="100dp" android:layout_height="100dp" android:layout_centerInParent="true" android:paddingLeft="10dp" android:paddingTop="10dp" android:paddingRight="10dp" android:paddingBottom="10dp" app:cpt_circle_color="#0AA4A2" app:cpt_text_color="#0AA4A2" app:cpt_max="100" app:cpt_progress="30" app:cpt_remain_circle_border_width="3dp" app:cpt_remain_circle_color="#EFEFF0" app:cpt_text_enable="true" />RelativeLayout>


        • Java代碼

        public class MainActivity extends AppCompatActivity {
        @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final CircleProgressWithTextView circleProgress = findViewById(R.id.circleProgress);
        //使用值動(dòng)畫(huà),不斷更新進(jìn)度 ValueAnimator animator = ValueAnimator.ofFloat(0, 100); animator.setInterpolator(new LinearInterpolator()); animator.setRepeatCount(ValueAnimator.INFINITE); animator.setRepeatMode(ValueAnimator.RESTART); animator.setDuration(3000); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Float cValue = (Float) animation.getAnimatedValue(); circleProgress.setProgress(cValue); } }); animator.start(); }}


        需要源碼的童鞋公眾號(hào)【龍旋】對(duì)話(huà)框回復(fù)關(guān)鍵字:miui,即可獲得。


        到這里就結(jié)束啦。

        瀏覽 38
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            成人午夜无码福利视频 | 丁香五月激情五月 | 国产69精品久久久久777 欧美日韩免费一区二区三区 | 亚洲福利影院 | 亚洲欧美suv精品8888日 | gay同性戒尺打屁股男男在线观看 | 久久精品日 | 亚洲黄色电影免费在线观看 | 美国 日本 韩国三级三级三级黄色A在线播放 | 国产精品丝袜诱惑 |