關(guān)于安卓自定義進度條(一)

效果如下圖第一個控件


image.png

源碼在文末

自定義一個漸變色的進度條,需要怎樣定義?又會遇到什么坑?
帶著這些問題,開始發(fā)車。

思考

1如何繪制

2遇到什么坑

如何繪制

只要安卓開發(fā)中,扯上了自定義控件這個字眼,那么,使用canvas就八九不離十了。本次實踐中,自定義的是一個進度條,那么,進度條,有什么最最基本要素?
(一)當前進度
(二)背景顏色
除了上述意外,還有一些要素,如:緩存進度等等。確實都是大同小異,只要了解實現(xiàn)的原理,那這些都是時間的產(chǎn)物而已。

話回正題,如何實現(xiàn)。
首先,定義好外部調(diào)用的時候,需要傳入什么參數(shù),這個很關(guān)鍵,定義不好,就會有很多返工的機會。
筆者針對當前開發(fā)需求,定義了一個外部傳入對象,代碼如下:

    //進度條背景色--resource color
    private int bgColor = R.color.color_a8a8a8;
    //進度條開始顏色
    private int progressStartColor = R.color.colorPrimaryDark;
    //進度條結(jié)束顏色
    private int progressEndColor = R.color.blue_light;
    //進度條圓角
    private int radius = 20;
    //進度條文字大小,文字顏色,顯示的文字
    private int textSize = 16;
    private int textColor = R.color.color_ffffff;
    private String text = "100%";
    //文字是否加粗
    private boolean textBold = false;
    //進度--最大100
    private int progress = 6;

上圖中的定義,基本滿足當時的需求了。定義好以后,就可以進行自定義view中的canvas開發(fā)了。

canvas繪制是有層級的,所以,繪制背景,是第一個操作,再者,就是當前進度,最后,就是進度的文字了。
其中,繪制的字體的時候,注意canvas的drawtext中,y的真正含義。具體可以自行了解開發(fā)文檔。
繪制進度條背景核心代碼如下:

  int radius = dp2px(mDrawInfo.getRadius());
  mPaint.setColor(getResources().getColor(mDrawInfo.getBgColor()));
  canvas.drawRoundRect(0, 0, mViewWidth, mViewHeight, radius, radius, mPaint);

其實就是一個drawRoundRect的api調(diào)用,沒什么特別的。

繪制當前進度核心代碼如下:

        mPaint.setShader(new LinearGradient(0, 0, mDrawProgress, mViewHeight,
                getResources().getColor(mDrawInfo.getProgressStartColor()),
                getResources().getColor(mDrawInfo.getProgressEndColor()),
                Shader.TileMode.CLAMP
        ));
        RectF rectProgress = new RectF(0, 0, mDrawProgress, mViewHeight);
        canvas.drawRoundRect(rectProgress, radius, radius, mPaint);

因為需求需要當前進度顯示一個漸變的顏色,所以,就要對paint畫筆對象,設(shè)置一個過渡效果,調(diào)用setShader對象即可。

最后,繪制文字,核心代碼如下:

  canvas.drawText(mDrawText, mDrawTextX,
  mViewHeight - mDrawTextHeightInterval, mPaint);

其實就是也是一個drawText方法調(diào)用,沒什么特別的。

至此,思路已經(jīng)說完了。但是實際開發(fā)中,會有一些地方需要注意的,下面開始發(fā)車。

遇到的問題

一、當畫筆對象setShader后,若下一個繪制操作不需要,記得要調(diào)用setShader(null)。否則會繼續(xù)保持。
二、對于進度值很少的時候,會出現(xiàn)一個很特別的情況,由于調(diào)用的是drawRoundRect方法,所以圓角的地方,會不重合,開發(fā)者可以試一下。
如何解決?這就要使用Paint.setXfermode的方法中的PorterDuff.Mode.SRC_IN方法。此外,還要禁用硬件加速setLayerType(View.LAYER_TYPE_SOFTWARE, null)。注意?。?!畫筆在調(diào)用setXfermode方法后,記得及時set null。

動畫

對于設(shè)置進度的動畫,用插值器實現(xiàn)就好,這里不一一敘述。

寫在最后

對于自定義控件,難的不是調(diào)用canvas的接口,而是調(diào)用完這些接口以后,如何保證結(jié)果如期,如何調(diào)整整合帶來的兼容問題。

that's all----------------------------------------------------------------------------------------------

代碼地址

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容