Android自定義View(環(huán)形進(jìn)度條)

1 前言

自定義view是android的一個(gè)難點(diǎn),逃避了那么久嗡载, 現(xiàn)在覺(jué)得不會(huì)的東西還是得要從基礎(chǔ)補(bǔ)起來(lái)窑多,自定義進(jìn)度條網(wǎng)上也一大堆,這篇文章只是一個(gè)入門(mén)的學(xué)習(xí)筆記洼滚,高手請(qǐng)略過(guò)...

2 view的工作流程

這里只說(shuō)自定義環(huán)形進(jìn)度條埂息,比較入門(mén)級(jí),所以只做簡(jiǎn)單介紹遥巴,顯得簡(jiǎn)潔千康,看著舒服,后續(xù)會(huì)講詳細(xì)的流程方法铲掐,所以先來(lái)看看view的大體工作流程拾弃。
a) measure 確實(shí)view的測(cè)量寬/高 (測(cè)三圍,看五官)
b) layout 確定view的四個(gè)頂點(diǎn)的位置 (站在舞臺(tái)位置)
c} ondraw 將view繪制到屏幕上 (打扮好出場(chǎng))

3 工作圖

4 流程步驟

  • 自定義view的相關(guān)屬性
 // 圓環(huán)的顏色
    private int ringColor = 0xFF00FF00;
    // 圓環(huán)進(jìn)度的顏色
    private int ringProgressColor = 0xFFFF0000;
    //圓環(huán)的寬度
    private int ringWidth = 10;
    // 字體大小
    private int textSize = 20;
    // 字體顏色
    private int textColor = 0xFF0000FF;
    // 當(dāng)前進(jìn)度
    private int currentProgress = 60;
    // 最大進(jìn)度
    private int maxProgress = 100;
    // 得到控件的寬度
    private int width;
    // 畫(huà)筆對(duì)象
    private Paint paint;
  • 在values下新建attr.xml
<!-- 自定義環(huán)形進(jìn)度條的屬性-->
    <declare-styleable name="RingProgressView">
        <attr name="ringColor" format="color"/>
        <attr name="ringProgressColor" format="color"/>
        <attr name="ringWidth" format="dimension"/>
        <attr name="textSize" format="dimension"/>
        <attr name="textColor" format="color"/>
        <attr name="currentProgress" format="integer"/>
        <attr name="maxProgress" format="integer"/>
    </declare-styleable>
  • 通過(guò)TypedArray獲取自定義view的相關(guān)屬性
 public RingProgressView(Context context) {
        this(context, null);
    }

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

    public RingProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        // 得到自定義資源數(shù)組
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RingProgressView);
        ringColor = typedArray.getColor(R.styleable.RingProgressView_ringColor, ringColor);
        ringProgressColor = typedArray.getColor(R.styleable.RingProgressView_ringProgressColor, ringProgressColor);
        ringWidth = (int) typedArray.getDimension(R.styleable.RingProgressView_ringWidth, dip2px(10));
        textSize = (int) typedArray.getDimension(R.styleable.RingProgressView_textSize, dip2px(20));
        textColor = typedArray.getColor(R.styleable.RingProgressView_textColor, textColor);
        currentProgress = typedArray.getInt(R.styleable.RingProgressView_currentProgress, currentProgress);
        maxProgress = typedArray.getColor(R.styleable.RingProgressView_maxProgress, maxProgress);
        typedArray.recycle();

        paint = new Paint();
        // 抗鋸齒
        paint.setAntiAlias(true);
    }
  • 畫(huà)同心圓
 // 1. 計(jì)算圓心坐標(biāo)及半徑
  float centerX = width / 2;
  float centerY = width / 2;
  float radius = width / 2 - ringWidth / 2;

  // 2. 畫(huà)圓環(huán)
  paint.setStyle(Paint.Style.STROKE);
  paint.setStrokeWidth(ringWidth);
  paint.setColor(ringColor);
  canvas.drawCircle(centerX, centerY, radius, paint);
  • 畫(huà)圓弧進(jìn)度
        // 3. 畫(huà)圓弧
        RectF rectF = new RectF(ringWidth / 2, ringWidth / 2, width - ringWidth / 2, width - ringWidth / 2);
        paint.setColor(ringProgressColor);
        canvas.drawArc(rectF, 0, currentProgress * 360 / maxProgress, false, paint);
  • 畫(huà)百分比文本框
        // 3. 畫(huà)文本
        String text = currentProgress * 100 / maxProgress + "%";
        paint.setColor(textColor);
        paint.setTextSize(textSize);
        // 要重新設(shè)置寬度為0
        paint.setStrokeWidth(0);
        // 得到指定文本邊界的指定大小
        Rect bounds = new Rect();
        paint.getTextBounds(text, 0, text.length(), bounds);
//        float textWidth = paint.measureText(text);
//        float textHigh = textSize;
        canvas.drawText(text, width / 2 - bounds.width() / 2, width / 2 + bounds.height() / 2, paint);

學(xué)習(xí)心得

  • 自定義屬性

1.通過(guò)新建attrs.xml迹炼,增加declare-styleable標(biāo)簽來(lái)定義相關(guān)的屬性
2.通過(guò)TypedArray獲取自定義的資源數(shù)組

  • getDimension砸彬、getDimensionPixelOffset、getDimensionPixelSize區(qū)別

getDimension和getDimensionPixelOffset的功能都是獲取某個(gè)dimen的值斯入,但是如果單位是dp或sp砂碉,則需要將其乘以density。如果是px刻两,則不乘增蹭。并且getDimension返回float,getDimensionPixelOffset返回int.
而getDimensionPixelSize則不管寫(xiě)的是dp磅摹,sp滋迈,px, 都會(huì)乘以denstiy.

  • Paint類(lèi)measureText與getTextBounds的區(qū)別

在使用Canvas繪制文字時(shí)霎奢,需要得到字符串的長(zhǎng)度,Paint類(lèi)內(nèi)給了兩個(gè)方法饼灿,measureText()幕侠,getTextBounds(),但是實(shí)際的寬度meauserText()要比getTextBounds()大一點(diǎn),但是相差不會(huì)太大

  • Paint畫(huà)圓的半徑之謎

為什么圓的半徑是radius = width / 2 - ringWidth / 2而不是width / 2 或者width / 2 - ringWidth?
其實(shí)我們畫(huà)的是圓環(huán)碍彭,有寬度的晤硕,Paint畫(huà)刷其實(shí)是從圓環(huán)的中心點(diǎn)繪制的,所以半徑是 width / 2 - ringWidth / 2庇忌,如果你不信舞箍,看下圖:

width / 2 - ringWidth

width / 2

自定義環(huán)形進(jìn)度條到此結(jié)束,感謝你的瀏覽
完整版代碼:戳這里

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末皆疹,一起剝皮案震驚了整個(gè)濱河市疏橄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌略就,老刑警劉巖捎迫,帶你破解...
    沈念sama閱讀 211,423評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異表牢,居然都是意外死亡立砸,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,147評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)初茶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人浊闪,你說(shuō)我怎么就攤上這事恼布。” “怎么了搁宾?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,019評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵折汞,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我盖腿,道長(zhǎng)爽待,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,443評(píng)論 1 283
  • 正文 為了忘掉前任翩腐,我火速辦了婚禮鸟款,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘茂卦。我一直安慰自己何什,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,535評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布等龙。 她就那樣靜靜地躺著处渣,像睡著了一般伶贰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上罐栈,一...
    開(kāi)封第一講書(shū)人閱讀 49,798評(píng)論 1 290
  • 那天黍衙,我揣著相機(jī)與錄音,去河邊找鬼荠诬。 笑死琅翻,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的浅妆。 我是一名探鬼主播望迎,決...
    沈念sama閱讀 38,941評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼凌外!你這毒婦竟也來(lái)了辩尊?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,704評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤康辑,失蹤者是張志新(化名)和其女友劉穎摄欲,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體疮薇,經(jīng)...
    沈念sama閱讀 44,152評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡胸墙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,494評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了按咒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片迟隅。...
    茶點(diǎn)故事閱讀 38,629評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖励七,靈堂內(nèi)的尸體忽然破棺而出智袭,到底是詐尸還是另有隱情,我是刑警寧澤掠抬,帶...
    沈念sama閱讀 34,295評(píng)論 4 329
  • 正文 年R本政府宣布吼野,位于F島的核電站,受9級(jí)特大地震影響两波,放射性物質(zhì)發(fā)生泄漏瞳步。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,901評(píng)論 3 313
  • 文/蒙蒙 一腰奋、第九天 我趴在偏房一處隱蔽的房頂上張望单起。 院中可真熱鬧,春花似錦劣坊、人聲如沸馏臭。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,742評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)括儒。三九已至绕沈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間帮寻,已是汗流浹背乍狐。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,978評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留固逗,地道東北人浅蚪。 一個(gè)月前我還...
    沈念sama閱讀 46,333評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像烫罩,于是被迫代替她去往敵國(guó)和親惜傲。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,499評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容