Android ShimmerLayout實(shí)現(xiàn)微光效果解析
前陣子在github上看到一個很不錯的動畫效果,叫做ShimmerLayout,是一個用于實(shí)現(xiàn)內(nèi)部視圖微光效果的布局。
如何實(shí)現(xiàn)
通過使用PorterDuff,我們可以制造出微光效果。PorterDuff是canvas繪制圖像處理中的一種渲染模式,當(dāng)我們需要繪制出區(qū)域覆蓋的圖形效果的時候,我們可以使用這種方式來繪制。
這里我們采用的是PorterDuff.MODE.SRC_IN,意思是在繪制的時候,顯示上下圖層相交的部分,且這部分顯示上層圖層。
1) 首先我們需要繪制出最上層的微光,這里通過LinearGradient線性漸變渲染器來繪制微光漸變效果,為了使得漸變自然,我們看到,代碼里在前后兩端都加入了透明色。
private Bitmap getSourceMaskBitmap() { if (sourceMaskBitmap != null) { return sourceMaskBitmap; } int width = maskRect.width(); int height = getHeight(); /* 通過LinearGradient在遮罩Bitmap上繪制漸變效果 */ final int edgeColor = reduceColorAlphaValueToZero(shimmerColor); LinearGradient gradient = new LinearGradient( -maskRect.left, 0, width + maskRect.left, 0, /* 透明色 - 微光顏色 - 微光顏色 - 透明色 */ new int[]{edgeColor, shimmerColor, shimmerColor, edgeColor}, new float[]{0.25F, 0.47F, 0.53F, 0.75F}, Shader.TileMode.CLAMP); Paint paint = new Paint(); paint.setShader(gradient); sourceMaskBitmap = createBitmap(width, height); /* 對微光效果的bitmap做一些旋轉(zhuǎn)效果 */ Canvas canvas = new Canvas(sourceMaskBitmap); canvas.rotate(shimmerAngle, width / 2, height / 2); canvas.drawRect(-maskRect.left, maskRect.top, width + maskRect.left, maskRect.bottom, paint); return sourceMaskBitmap; }
2)、然后,我們需要把微光效果的圖層和視圖本身的界面混合,使用PorterDuff.MODE.SRC_IN混合效果。首先如何繪制視圖本身的界面,這里很簡單,直接調(diào)用父類的繪制方法super.dispatchDraw(Canvas),緊接著再繪制微光效果的圖層。
/* 獲取微光效果Bitmap */ localMaskBitmap = getSourceMaskBitmap(); canvas.save(); /* 先繪制GroupView本身的界面 */ super.dispatchDraw(canvas); /* 再繪制微光效果Bitmap */ canvas.drawBitmap(localMaskBitmap, 0, 0, maskPaint); canvas.restore();
3) 最后我們發(fā)現(xiàn),微光效果是從左向右移動過去的,如何實(shí)現(xiàn)?
通過不斷位移localMaskBitmap的位置,這里通過控制偏移值maskOffsetX,實(shí)現(xiàn)了微光慢慢位移的效果。
/* 獲取微光效果Bitmap */ localMaskBitmap = getSourceMaskBitmap(); canvas.save(); /* canvas 裁剪顯示 */ canvas.clipRect(maskOffsetX, 0, maskOffsetX + localMaskBitmap.getWidth(), getHeight()); /* 先繪制GroupView本身的界面 */ super.dispatchDraw(canvas); /* 再繪制微光效果Bitmap */ canvas.drawBitmap(localMaskBitmap, maskOffsetX, 0, maskPaint); canvas.restore();
這個動畫原理本身很簡單,不過在內(nèi)存方面,因?yàn)閯?chuàng)建了多個bitmap,如果當(dāng)前界面不包含大圖,對內(nèi)存的消耗還是很低的,適用于為比較輕量級的界面添加效果。
更多細(xì)節(jié),看看作者的原文介紹以及GitHub
ShimmerLayout Github : https://github.com/team-supercharge/ShimmerLayout
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
淺談AnDroidDraw+DroidDraw實(shí)現(xiàn)Android程序UI設(shè)計(jì)的分析說明
本篇文章是對AnDroidDraw+DroidDraw實(shí)現(xiàn)Android程序UI設(shè)計(jì)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05Android使用socket進(jìn)行二進(jìn)制流數(shù)據(jù)傳輸
這篇文章主要介紹了Android使用socket進(jìn)行二進(jìn)制流數(shù)據(jù)傳輸,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-04-04Android中AlertDialog的六種創(chuàng)建方式
這篇文章主要介紹了Android中AlertDialog的六種創(chuàng)建方式的相關(guān)資料,需要的朋友可以參考下2016-07-07Android中通過MediaStore獲取音樂文件信息方法
這篇文章主要介紹了Android中通過MediaStore獲取音樂文件信息方法,本文講解了獲取歌曲的名稱、歌曲的專輯名、歌曲的歌手名、歌曲文件的全路徑、歌曲文件的名稱、歌曲文件的發(fā)行日期等音樂文件信息的方法,需要的朋友可以參考下2015-04-04Flutter使用sqflite處理數(shù)據(jù)表變更的方法詳解
了解過數(shù)據(jù)庫的同學(xué)應(yīng)該會知道,數(shù)據(jù)表結(jié)構(gòu)是可能發(fā)生改變的。所以本文為大家介紹了Flutter?使用?sqflite?處理數(shù)據(jù)表變更的版本升級處理方法,感興趣的可以了解一下2023-04-04Android客戶端實(shí)現(xiàn)注冊、登錄詳解(1)
這篇文章主要為大家詳細(xì)介紹了Android客戶端實(shí)現(xiàn)注冊、登錄代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-09-09詳解Kotlin Android開發(fā)中的環(huán)境配置
這篇文章主要介紹了詳解Kotlin Android開發(fā)中的環(huán)境配置的相關(guān)資料,需要的朋友可以參考下2017-06-06