Android ShimmerLayout實(shí)現(xiàn)微光效果解析
前陣子在github上看到一個(gè)很不錯(cuò)的動(dòng)畫(huà)效果,叫做ShimmerLayout,是一個(gè)用于實(shí)現(xiàn)內(nèi)部視圖微光效果的布局。

如何實(shí)現(xiàn)
通過(guò)使用PorterDuff,我們可以制造出微光效果。PorterDuff是canvas繪制圖像處理中的一種渲染模式,當(dāng)我們需要繪制出區(qū)域覆蓋的圖形效果的時(shí)候,我們可以使用這種方式來(lái)繪制。
這里我們采用的是PorterDuff.MODE.SRC_IN,意思是在繪制的時(shí)候,顯示上下圖層相交的部分,且這部分顯示上層圖層。

1) 首先我們需要繪制出最上層的微光,這里通過(guò)LinearGradient線性漸變渲染器來(lái)繪制微光漸變效果,為了使得漸變自然,我們看到,代碼里在前后兩端都加入了透明色。
private Bitmap getSourceMaskBitmap() {
if (sourceMaskBitmap != null) {
return sourceMaskBitmap;
}
int width = maskRect.width();
int height = getHeight();
/* 通過(guò)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);
/* 對(duì)微光效果的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混合效果。首先如何繪制視圖本身的界面,這里很簡(jiǎn)單,直接調(diào)用父類(lèi)的繪制方法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),微光效果是從左向右移動(dòng)過(guò)去的,如何實(shí)現(xiàn)?
通過(guò)不斷位移localMaskBitmap的位置,這里通過(guò)控制偏移值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();
這個(gè)動(dòng)畫(huà)原理本身很簡(jiǎn)單,不過(guò)在內(nèi)存方面,因?yàn)閯?chuàng)建了多個(gè)bitmap,如果當(dāng)前界面不包含大圖,對(duì)內(nèi)存的消耗還是很低的,適用于為比較輕量級(jí)的界面添加效果。
更多細(xì)節(jié),看看作者的原文介紹以及GitHub
ShimmerLayout Github : https://github.com/team-supercharge/ShimmerLayout
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)注Ionic底部導(dǎo)航按鈕tabs在android情況下浮在上面的處理
Ionic是一款流行的移動(dòng)端開(kāi)發(fā)框架,但是剛?cè)腴T(mén)的同學(xué)會(huì)發(fā)現(xiàn),Ionic在iOS和Android的底部tabs顯示不一樣。在安卓情況下底部tabs會(huì)浮上去,下面給大家介紹下實(shí)現(xiàn)代碼,一起看看吧2016-12-12
Android Drawerlayout側(cè)拉欄事件傳遞問(wèn)題的解決方法
這篇文章主要為大家詳細(xì)介紹了Android Drawerlayout側(cè)拉欄事件傳遞問(wèn)題的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
Android開(kāi)發(fā) Activity和Fragment詳解
本文主要介紹Android開(kāi)發(fā) Activity和Fragment,這里對(duì)Activity和Fragment的知識(shí)做了詳細(xì)講解,并附簡(jiǎn)單代碼示例,有興趣的小伙伴可以參考下2016-08-08
Eclipse工程轉(zhuǎn)為兼容Android Studio模式的方法步驟圖文詳解
這篇文章主要介紹了Eclipse工程轉(zhuǎn)為兼容Android Studio模式的方法步驟,本文圖文并茂給大家介紹的非常詳細(xì),需要的朋友可以參考下2017-12-12
Android 5.0及以上編程實(shí)現(xiàn)屏幕截圖功能的方法
這篇文章主要介紹了Android 5.0及以上編程實(shí)現(xiàn)屏幕截圖功能的方法,結(jié)合實(shí)例形式分析了Android5.0以上實(shí)現(xiàn)截圖功能的相關(guān)類(lèi)、函數(shù)及權(quán)限控制等操作技巧,需要的朋友可以參考下2018-01-01
Android中TextView顯示插入的圖片實(shí)現(xiàn)方法
這篇文章主要介紹了Android中TextView顯示插入的圖片實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了TextView三種顯示插入圖片的實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-08-08
Android android:exported = true 用法詳解
在本篇文章里小編給大家整理了關(guān)于Android android:exported = true 用法,需要的朋友們參考下。2019-09-09

