1. 程式人生 > >拒絕第三方--手把手教你自定義進度條

拒絕第三方--手把手教你自定義進度條

還在為了一個小小的效果,依賴一個一個的第三方?

看著別人隨隨便便寫了一個自定義效果,自己卻除了666啥也做不了?

如果你認為自己就是這樣,那麼,你要好好看一下這篇文章了!

進度條作為移動開發的一個常用功能,相信你一定不陌生。本篇,我們要手動編寫一個簡單的進度條,模擬一下下載的效果。

一、效果

二、分析

自定義View,分析裡面的元素:

1、進度條背景顏色

2、進度條背景是否是實心

3、進度條的顏色

4、進度(文字)的顏色和字型大小

5、進度條的圓角大小

三、實現

1、自定義View類,繼承View

public class CustomProgressView extends View {

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

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

    public CustomProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);


    }

2、在attr檔案中,定義樣式

    <declare-styleable name="CustomProgressView">
        <!--百分比文字大小-->
        <attr name="cp_percent_textsize" format="dimension"/>
        <!--百分比文字顏色-->
        <attr name="cp_percent_textcolor" format="color|integer"/>
        <!--進度條背景顏色-->
        <attr name="cp_background_color" format="color|integer"/>
        <!--進度條背景是否空心-->
        <attr name="cp_background_is_stroke" format="boolean"/>
        <!--進度條顏色-->
        <attr name="cp_progress_color" format="color|integer"/>
        <!--進度條圓角值-->
        <attr name="cp_rect_round" format="dimension"/>

    </declare-styleable>

定義元素,並賦予正確的屬性型別。

3、在構造方法中,呼叫obtainStyledAttributes方法,獲取自定義的style,並初始化個屬性,同時,初始化畫筆Paint

    private int     cp_percent_textsize     = 18;//百分比字型大小
    private int     cp_percent_textcolor    = 0xff009ACD;
    private int     cp_background_color     = 0xff636363;
    private int     cp_progress_color       = 0xff00C5CD;
    private boolean cp_background_is_stroke = true;
    private int     cp_rect_round           = 5;
    private Paint mPaint;
    private int   mCenterX;
    private int   mCenterY;

    private int progressCurrent = 0;
    private int progressMax     = 100;


    public CustomProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray typedArray = context.obtainStyledAttributes(R.styleable.CustomProgressView);
        cp_percent_textsize = (int) typedArray.getDimension(R.styleable.CustomProgressView_cp_percent_textsize, cp_percent_textsize);
        cp_percent_textcolor = typedArray.getColor(R.styleable.CustomProgressView_cp_percent_textcolor, cp_percent_textcolor);
        cp_background_color = typedArray.getColor(R.styleable.CustomProgressView_cp_background_color, cp_background_color);
        cp_progress_color = typedArray.getColor(R.styleable.CustomProgressView_cp_progress_color, cp_progress_color);
        cp_background_is_stroke = typedArray.getBoolean(R.styleable.CustomProgressView_cp_background_is_stroke, cp_background_is_stroke);
        cp_rect_round = (int) typedArray.getDimension(R.styleable.CustomProgressView_cp_rect_round, cp_rect_round);
        typedArray.recycle();

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    }

4、複寫最重要的方法onDraw

    @Override
    protected void onDraw(Canvas canvas) {
        mCenterX = getWidth() / 2;
        mCenterY = getHeight() / 2;

        drawHorProgress(mPaint, canvas);

    }

    private void drawHorProgress(Paint paint, Canvas canvas) {
        //畫背景
        paint.setColor(cp_background_color);
        if (cp_background_is_stroke) {
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeWidth(1);
        } else {
            paint.setStyle(Paint.Style.FILL);
        }

        canvas.drawRoundRect(new RectF(mCenterX - getWidth() / 2, mCenterY - getHeight() / 2,
                mCenterX + getWidth() / 2, mCenterY + getHeight() / 2), cp_rect_round, cp_rect_round, paint);

        //畫進度條
        paint.setColor(cp_progress_color);
        paint.setStyle(Paint.Style.FILL);

        canvas.drawRoundRect(new RectF(mCenterX - getWidth() / 2, mCenterY - getHeight() / 2,
                (int) (progressCurrent * getWidth() / progressMax), mCenterY + getHeight() / 2), cp_rect_round, cp_rect_round, paint);

        //畫文字
        paint.setColor(cp_percent_textcolor);
        paint.setTextSize(cp_percent_textsize);
        paint.setStyle(Paint.Style.FILL);
        String value_str = (int) (progressCurrent * 100 / progressMax) + "%";
        Rect rect = new Rect();
        paint.getTextBounds(value_str, 0, value_str.length(), rect);

        float textWidth = rect.width();
        float textHeight = rect.height();
        if (textWidth >= getWidth()) {
            textWidth = getWidth();
        }
        Paint.FontMetrics metrics = paint.getFontMetrics();
        float baseline = (getMeasuredHeight() - metrics.bottom + metrics.top) / 2 - metrics.top;
        canvas.drawText(value_str, mCenterX - textWidth / 2, baseline, paint);

    }

步驟:

1、想一下,其實很簡單。

        進度條背景和進度條,就是兩個圓角矩形疊加在一起。最後再把文字畫在矩形的中間位置。

2、找到View的中心點,getWidth / 2 , getHeight / 2。

3、畫背景。

        其實背景很簡單。固定的圓角矩形。left、top、right、bottom座標其實是固定的。根據中心點,很容易畫出來。

4、畫進度條。

        進度條是根據的進度值的變化實時重新整理的。所以我們要定義一個當前進度progressCurrent和最大進度progressMax。

        為什麼要定義最大進度?實際生產中,你要根據下載檔案的總大小和當前已經下載的大小來計算進度,所以這個是要設定的。

        仔細分析,可以知道,在你畫進度條的時候,其實只有一個座標值是變化的,那就是 right 。你可以根據當前進度的百分比來計算當前精度下的 right 佔寬度的多少比例。

5、畫文字

        使文字居中的baseline是一個知識點,需要重點掌握。

6、給各屬性值設定setter和getter方法。

         這裡主要說一下,進度值的設定。

    public int getProgressCurrent() {
        return progressCurrent;
    }

    public void setProgressCurrent(int progressCurrent) {
        if (progressCurrent > progressMax) {
            this.progressCurrent = progressMax;
        } else {
            this.progressCurrent = progressCurrent;
        }
        postInvalidate();
    }

噹噹前進度超過最大進度時,當前進度設定為最大進度。(當前進度為100%的下一秒,就會出現超過最大進度的情況)

記得重新繪製View 呼叫postInvalidate();方法。

5、佈局

 <net.feelingtech.example_work.custom.ownprogress.CustomProgressView
        android:id="@+id/cpv_one"
        android:layout_width="match_parent"
        android:layout_height="15dp" />

6、跑起來

        mCustomProgressView = view.findViewById(R.id.cpv_one);
        mCustomProgressView.setProgressMax(100);
        mCustomProgressView.setCp_background_color(Color.parseColor("#A2CD5A"));
        mCustomProgressView.setCp_percent_textcolor(Color.RED);
        mCustomProgressView.setCp_rect_round(16);
        mCustomProgressView.setCp_background_is_stroke(false);
        mCustomProgressView.setCp_percent_textsize(30);

        view.findViewById(R.id.bt_start).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (progressCurrent != 0) {
                    progressCurrent = 0;
                    return;
                }
                mRunnable = new Runnable() {
                    @Override
                    public void run() {

                        progressCurrent += 1;
                        mCustomProgressView.setProgressCurrent(progressCurrent);
                        mHandler.postDelayed(mRunnable, 5);

                    }
                };
                mHandler.postDelayed(mRunnable, 1);
            }
        });

OVER ! ! !

                                                                          掃碼關注,共同進步

相關推薦

拒絕第三方--手把手定義進度

還在為了一個小小的效果,依賴一個一個的第三方? 看著別人隨隨便便寫了一個自定義效果,自己卻除了666啥也做不了? 如果你認為自己就是這樣,那麼,你要好好看一下這篇文章了! 進度條作為移動開發的一個常用功能,相信你一定不陌生。本篇,我們要手動編寫一個簡單的進度條,模擬一下

[C#] (原創)一步一步定義控制元件——04,ProgressBar(進度

一、前言 技術沒有先進與落後,只有合適與不合適。 本篇的自定義控制元件是:進度條(ProgressBar)。 進度條的實現方式多種多樣,主流的方式有:使用多張圖片去實現、使用1個或2個Panel放到UserControl上去實現、過載系統進度條去實現等等。 本次所實現的進度條仍是使用GDI+去實現。當然,如果

Android 手把手定義ViewGroup 一

                最近由於工作的變動,導致的部落格的更新計劃有點被打亂,希望可以儘快脈動回來~今天給大家帶來一篇自定義ViewGroup的教程,說白了,就是教大家如何自定義ViewGroup,如果你對自定義ViewGroup還不是很瞭解,或者正想學習如何自定義,那麼你可以好好看看這篇部落格。1、

Android 手把手定義ViewGroup(一)

最近由於工作的變動,導致的部落格的更新計劃有點被打亂,希望可以儘快脈動回來~今天給大家帶來一篇自定義ViewGroup的教程,說白了,就是教大家如何自定義ViewGroup,如果你對自定義ViewGroup還不是很瞭解,或者正想學習如何自定義,那麼你可以好好看看這篇部落格。1、概述在寫程式碼之前,我必須得

IOS-一步一步定義評分星級RatingBar

//  RatingBar.m // //  Created by HailongHan on 15/1/1. //  Copyright (c) 2015年 cubead. All rights reserved. // #import "RatingBar.h" @interface RatingBar

[C#] (原創)一步一步定義控制元件——02,ScrollBar(滾動

一、前言 技術沒有先進與落後,只有合適與不合適。 本篇的自定義控制元件是:滾動條(ScollBar)。 我們可以在網上看到很多自定義的滾動條控制元件,它們大都是使用UserControl去做,即至少使用一個Panel或其它控制元件作滑塊,使用UserControl本身或另一個控制元件作為背景條,而有的複雜的還

[C#] (原創)一步一步定義控制元件——03,SwitchButton(開關按鈕)

一、前言 技術沒有先進與落後,只有合適與不合適。 本篇的自定義控制元件是:開關按鈕(SwitchButton)。 開關按鈕非常簡單,實現方式也多種多樣,比如常見的:使用兩張不同的按鈕圖片,代表開和關,然後在點選時切換這兩張圖片。 而本篇和前兩篇一脈相承,都是繼承Control,使用GDI+去實現。因為都是相同

[C#] (原創)一步一步定義控制元件——05,Label(原生控制元件)

一、前言 技術沒有先進與落後,只有合適與不合適。 自定義控制元件可以分為三類: 一類是“無中生有”。就如之前文章中的的那些控制元件,都是繼承基類Control,來實現特定的功能效果; 一類是“有則改之”。是對原生控制元件的改造,以達到特定的功能效果; 一類是“使用者控制元件”。是將多個控制元件進行組合,以實現

[C#] (原創)一步一步定義控制元件——06,MaskLayer(遮罩層)

一、前言 技術沒有先進與落後,只有合適與不合適。 本篇的自定義控制元件是:遮罩層(MaskLayer)。 遮罩層對軟體的美觀與易用性上的提高是很大的,在日常使用過程中也會經常看到各種遮罩層,雖然WinForm本身沒有原生的遮罩層控制元件,但實現起來並不麻煩。 遮罩層的實現方式一般有兩種:一種是基於自定義控制元

【專案實踐】手把手建高效能物件儲存伺服器

![物件儲存.png](https://img2020.cnblogs.com/blog/1496775/202103/1496775-20210310095045009-259334496.jpg) > 以專案驅動學習,以實踐檢驗真知 物件儲存的應用範圍非常廣泛,小至圖床、檔案服務,大至大資料應用。無論

aNDROID定義進度顏色

定義 hao123 自定義進度條 com list andro 顏色 androi baidu DIaLOGFRaGMENT%E9%97%AE%E9%A2%98%E6%B1%82%E8%A7%A3 http://music.baidu.com/songlist/49564

vue定義進度的製作方法(含css屬性值的兩種動態改變方式)

雛形部分接上一篇文章:https://blog.csdn.net/ColourfulTiger/article/details/82910505 結合vue製作自定義的進度條,優勢在於採用了vue特有的樣式繫結,與雙向繫結的方法,達到資料與進度條的進度一致。 突破點:通過變數來動態改變屬性對

C#定義進度,可用於音樂播放器進度調整,音量調整等功能

平時在做c#專案時偶爾會碰到要使用進度條的情況,但c#自帶的進度條外觀往往不合我們心意,這就需要我們自己動手來只做一款自己的進度條。先上圖:        外觀雖然簡單,但感覺比c#自帶的好看多了。 繪製這樣一個進度條需要兩個基本控制元件,兩個La

Android帶圓形數字進度定義進度

開發 設計搞了一個帶圓形進度的進度條,在GitHub上逛了一圈,發現沒有,自己擼吧。 先看介面效果: 主要思路是寫一個繼承ProgressBar的自定義View,不廢話,直接上程式碼: package com.fun.progressbarwithn

Android 各種定義進度Progressbar

Android 自定義進度條 Progressbar 控制元件集合 Seekbar with labelled intervals Like Olx FilterView Seekbar Android-ProgressViews

定義進度之圓角進度問題

Android自定義進度條是開發中比較常見的一個需求,在之前的部落格中也介紹過如何通過自定義ProgressBar的樣式來實現自定義水平進度條和環形進度條。本文主要是對近期一個專案中的圓角進度條的實現做一個記錄。 設計給出的圖是這樣的: 拿到設計圖,對於

Android-定義View-定義進度

眼看6月到了,由於前段時間域名備案等原因,伺服器關閉了差不多一個月,所以沒更新文章,索性今天補一篇吧,準備寫一個簡單的自定義View,就拿進度條做這個需求吧,雖然簡單,但是也包含了基本自定義View的幾要素,比如自定義屬性、重寫測量、重寫繪製等功能。 需求

小程式視訊定義進度

大體思路:先在wxml檔案中定義一個進度條,然後在視訊上定義播放進度變化時觸發bindtimeupdate這個屬性,進而進度條值改變觸發sliderChanging()和sliderChange()方法。 1、定義進度條 <view class='process-

Android簡單定義進度(小白進)

今天,我在騰訊課堂學習了自定義一個進度條,視訊連結:https://ke.qq.com/course/144239#term_id=100163342,我根據此視訊教程,寫了關於此程式碼的詳細註釋,非常簡單,非常適合小白學習。 主要步驟是: 1.

Ftp上傳下載檔案,並能定義進度展示(FtpClient)

前一段時間,自己寫了一個java專案釋出在一個免費的java平臺上但是該平臺給專案的是虛擬路徑並不能上傳檔案。後來想到應用ftp作為上傳檔案的儲存器。 ftp上傳的工具類有sun(sun.net.*)和apache(org.apache.commons.net.ftp.*