Android UI:控件占位加載的Drawable

Android UI | 控件占位加載的Drawable

本文未經(jīng)授權(quán),切勿轉(zhuǎn)載

嗨,各位路過的小伙伴大家好。由于工作原因,已經(jīng)快鴿了好長時(shí)間不更新文章了,這次就先介紹用于控件占位加載的動畫,基于自定義Drawable實(shí)現(xiàn)的。

Drawable是什么

1、一種可以在Canvas上進(jìn)行繪制的抽象的概念
2、顏色、圖片等都可以是一個(gè)Drawable
3、Drawable可以通過XML定義,或者通過代碼創(chuàng)建</font>**
4、Android中Drawable是一個(gè)抽象類,每個(gè)具體的Drawable都是其子類

自定義Drawable優(yōu)勢

1、使用簡單,比自定義View成本低
2、非圖片類的Drawable所占空間小,能減小apk大小

實(shí)現(xiàn)加載動畫的Drawable

按慣例我們先直接看效果:

image

<font face="STCAIYUN" color="#0099ff">代碼分析</font>

這次分析代碼我們從需要什么,到如何實(shí)現(xiàn)進(jìn)行一步步講解

1、我們需要什么

既然我們是需要實(shí)現(xiàn)自定義Drawable,那么第一步肯定是新建一個(gè)類并繼承Drawalbe,我這里繼承的是ShapeDrawable

class PlaceHolderDrawable: ShapeDrawable()

接下來就是畫圖,我們可以看到我們的自定義Drawable也是有Canvas這個(gè)方法,和自定義View很像。然后這個(gè)加載動畫中間白色部分從左到右滑動,然后有漸變效果,可以知道這個(gè)就是我們熟悉的漸變色的Drawable,這個(gè)是我們在xml上面自定義Drawable經(jīng)常使用到的。先看代碼:

 private var mGradientCanvas: Canvas? = null //柱狀漸變色的Canvas
 private var mGradientLayer: Bitmap? = null 

 private var mBackgroundCanvas: Canvas? = null //背景Canvas
 private var mBackgroundLayer: Bitmap? = null
 
 private val floatArray = floatArrayOf( 0f,0.4f,0.8f)
    
  override fun draw(canvas: Canvas) {
        super.draw(canvas)
        
        shape.draw(mBackgroundCanvas, paint)

        canvas.drawBitmap(mBackgroundLayer!!, 0f, 0f, paint)

        xStartCoordinate = animatedValue
        xEndCoordinate = xStartCoordinate + mCanvasWidth/2

        paint.shader = LinearGradient(xStartCoordinate, 0f, xEndCoordinate, 0f, mColors, floatArray, Shader.TileMode.CLAMP)
        shape.draw(mGradientCanvas, paint)
        canvas.drawBitmap(mGradientLayer!!, 0f, 0f, paint)

    }

其中LinearGradient的源碼是這樣解釋的:

  /**
     * Create a shader that draws a linear gradient along a line.
     *
     * @param x0           The x-coordinate for the start of the gradient line
     * @param y0           The y-coordinate for the start of the gradient line
     * @param x1           The x-coordinate for the end of the gradient line
     * @param y1           The y-coordinate for the end of the gradient line
     * @param colors       The sRGB colors to be distributed along the gradient line
     * @param positions    May be null. The relative positions [0..1] of
     *                     each corresponding color in the colors array. If this is null,
     *                     the the colors are distributed evenly along the gradient line.
     * @param tile         The Shader tiling mode
     */
    public LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int[] colors,
            @Nullable float[] positions, @NonNull TileMode tile) {
        this(x0, y0, x1, y1, convertColors(colors), positions, tile,
                ColorSpace.get(ColorSpace.Named.SRGB));
    }

第一個(gè)參數(shù)為線性起點(diǎn)的x坐標(biāo)
第二個(gè)參數(shù)為線性起點(diǎn)的y坐標(biāo)
第三個(gè)參數(shù)為線性終點(diǎn)的x坐標(biāo)
第四個(gè)參數(shù)為線性終點(diǎn)的y坐標(biāo)
第五個(gè)參數(shù)為實(shí)現(xiàn)漸變效果的顏色的組合
第六個(gè)參數(shù)為前面的顏色組合中的各顏色在漸變中占據(jù)的位置(比重)
第七個(gè)參數(shù)為渲染器平鋪的模式,一共有三種

詳細(xì)介紹各參數(shù)區(qū)別可以參考以下文章
http://www.itdecent.cn/p/a9d09cb7577f

然后再把移動的動畫加進(jìn)去,就可以做到效果了

private val interpolator = LinearInterpolator()
private var animatedValue = 0f
fun setupAnimator() {
        xStartCoordinate = 0f //偏移量
        valueAnimator = ValueAnimator.ofFloat(- mCanvasWidth.toFloat()/3, mCanvasWidth.toFloat())
        valueAnimator?.duration = duration
        valueAnimator?.interpolator = interpolator
        valueAnimator?.repeatMode = ValueAnimator.RESTART
        valueAnimator?.repeatCount = ValueAnimator.INFINITE
        valueAnimator?.addUpdateListener { animation ->
            animatedValue = animation.animatedValue as Float
            invalidateSelf()
        }
        valueAnimator?.start()
    }
    

原理十分簡單就是利用X軸的不斷偏移,然后一直繪制從而達(dá)到效果
其實(shí)是大致上已經(jīng)完成了這個(gè)功能了,剩下就是Drawable的長寬高獲取顏色,以及如何管理,詳細(xì)可以到我GitHub上看源碼,有問題可以在掘金或者Github上的Issue留言,如果有問題不清楚建議在Issue留言,因?yàn)槲掖贕ithub的時(shí)間多于掘金。
https://github.com/ShowMeThe/PlaceHolder

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

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