Android利用ShaderMask實(shí)現(xiàn)花里胡哨的文字特效
前言
我們的 App 大部分時(shí)候的文字都是一種顏色,實(shí)際上,文字的顏色也可以多姿多彩。我們今天就來(lái)介紹一個(gè)能夠輕松實(shí)現(xiàn)文字漸變色的組件 —— ShaderMask
。ShaderMask
能夠構(gòu)建一個(gè)著色器(shader),然后覆蓋(mask)到它的子組件上,從而改變子組件的顏色。
ShaderMask 實(shí)現(xiàn)漸變色文字
ShaderMask
的構(gòu)造函數(shù)定義如下。
const ShaderMask({ Key? key, required this.shaderCallback, this.blendMode = BlendMode.modulate, Widget? child, })
其中關(guān)鍵的參數(shù)是 shaderCallback
回調(diào)方法,通過(guò) 回調(diào)方法可以構(gòu)建一個(gè)著色器來(lái)為子組件著色,典型的做法是使用 Gradient
的子類(如 LinearGradient
和 RadialGradial
)來(lái)創(chuàng)建著色器。blendMode
參數(shù)則用于設(shè)置著色的方式。 因此,我們可以利用LinearGradient
來(lái)實(shí)現(xiàn)漸變色文字,示例代碼如下,其中 blendMode
選擇為 BlendMode.srcIn
是忽略子組件原有的顏色,使用著色器來(lái)對(duì)子組件著色。
ShaderMask( shaderCallback: (rect) { return LinearGradient( begin: Alignment.centerLeft, end: Alignment.centerRight, colors: [ Colors.blue, Colors.green[300]!, Colors.orange[400]!, Colors.red, ], ).createShader(rect); }, blendMode: BlendMode.srcIn, child: const Text( '島上碼農(nóng)', style: TextStyle( fontSize: 36.0, fontWeight: FontWeight.bold, ), ), ),
實(shí)現(xiàn)效果如下圖。
實(shí)際上,不僅僅能夠?qū)ξ淖种?,還可以對(duì)圖片著色,比如我們使用一個(gè) Row
組件在文字前面增加一個(gè)Image
組件,可以實(shí)現(xiàn)下面的效果。
讓漸變色動(dòng)起來(lái)
靜態(tài)的漸變色著色還不夠,Gradient
還有個(gè) transform
來(lái)實(shí)現(xiàn)三維空間變換的漸變效果,我們可以利用這個(gè)參數(shù)和動(dòng)畫(huà)組件實(shí)現(xiàn)動(dòng)畫(huà)效果,比如下面這樣。
這里其實(shí)就是使用了動(dòng)畫(huà)控制 transform
實(shí)現(xiàn)橫向平移。由于 transform
是一個(gè) GradientTransform
類,實(shí)現(xiàn)這樣的效果需要定義一個(gè)GradientTransform
子類,如下所示。
@immutable class SweepTransform extends GradientTransform { const SweepTransform(this.dx, this.dy); final double dx; final double dy; @override Matrix4 transform(Rect bounds, {TextDirection? textDirection}) { return Matrix4.identity()..translate(dx, dy); } @override bool operator ==(Object other) { if (identical(this, other)) { return true; } if (other.runtimeType != runtimeType) { return false; } return other is SweepTransform && other.dx == dx && other.dy == dy; } @override int get hashCode => dx.hashCode & dy.hashCode; }
然后通過(guò) Animation
動(dòng)畫(huà)對(duì)象的值控制漸變色平移的距離就可以實(shí)現(xiàn)漸變色橫向掃過(guò)的效果了,代碼如下所示。
ShaderMask( shaderCallback: (rect) { return LinearGradient( begin: Alignment.centerLeft, end: Alignment.centerRight, colors: [ Colors.blue, Colors.green[300]!, Colors.orange[400]!, Colors.red, ], transform: SweepTransform( (_animation.value - 0.5) * rect.width, 0.0), ).createShader(rect); }, blendMode: BlendMode.srcIn, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( 'images/logo.png', scale: 2, ), const Text( '島上碼農(nóng)', style: TextStyle( fontSize: 36.0, fontWeight: FontWeight.bold, ), ), ], ), ),
圖片填充
除了使用漸變色之外,我們還可以利用 ImageShader 使用圖片填充文字,實(shí)現(xiàn)一些其他的文字特效,比如用火焰圖片作為背景,讓文字看起來(lái)像燃燒了一樣。
實(shí)現(xiàn)的代碼如下,其中動(dòng)效是通過(guò) ImageShader
的構(gòu)造函數(shù)的第4個(gè)參數(shù)的矩陣matrix4運(yùn)算實(shí)現(xiàn)的,相當(dāng)于是讓填充圖片移動(dòng)來(lái)實(shí)現(xiàn)火焰往上升的效果。
ShaderMask( shaderCallback: (rect) { return ImageShader( fillImage, TileMode.decal, TileMode.decal, (Matrix4.identity() ..translate(-20.0 * _animation.value, -150.0 * _animation.value)) .storage); }, blendMode: BlendMode.srcIn, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( 'images/logo.png', scale: 2, ), const Text( '島上碼農(nóng)', style: TextStyle( fontSize: 36.0, fontWeight: FontWeight.bold, ), ), ], ), )
總結(jié)
本篇介紹了 ShaderMask
組件的應(yīng)用,通過(guò) ShaderMask
組件我們可以對(duì)子組件進(jìn)行著色,從而改變子組件原來(lái)的顏色,實(shí)現(xiàn)如漸變色填充、圖片填充等效果。本篇完整源碼已提交至:實(shí)用組件相關(guān)源碼。
到此這篇關(guān)于Android利用ShaderMask實(shí)現(xiàn)花里胡哨的文字特效的文章就介紹到這了,更多相關(guān)Android ShaderMask文字特效內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android Jetpack組件庫(kù)LiveData源碼深入探究
LiveData是Jetpack組件的一部分,更多的時(shí)候是搭配ViewModel來(lái)使用,相對(duì)于Observable,LiveData的最大優(yōu)勢(shì)是其具有生命感知的,換句話說(shuō),LiveData可以保證只有在組件( Activity、Fragment、Service)處于活動(dòng)生命周期狀態(tài)的時(shí)候才會(huì)更新數(shù)據(jù)2022-09-09Flutter UI實(shí)現(xiàn)側(cè)拉抽屜菜單
這篇文章主要為大家詳細(xì)介紹了Flutter UI實(shí)現(xiàn)側(cè)拉抽屜菜單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03Android ExpandableListView單選以及多選實(shí)現(xiàn)代碼
這篇文章主要為大家詳細(xì)介紹了Android ExpandableListView單選以及多選的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06Android仿外賣(mài)購(gòu)物車(chē)功能
這篇文章主要為大家詳細(xì)介紹了Android仿外賣(mài)購(gòu)物車(chē)功能的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-06-06Android移動(dòng)應(yīng)用開(kāi)發(fā)指南之六種布局詳解
Android應(yīng)用界面要美觀好看,就需要運(yùn)用到一定的布局技術(shù),Android布局是不可忽視的,是android應(yīng)用界面開(kāi)發(fā)的重要一環(huán),這篇文章主要給大家介紹了關(guān)于Android移動(dòng)應(yīng)用開(kāi)發(fā)指南之六種布局的相關(guān)資料,需要的朋友可以參考下2022-09-09Android編程使用內(nèi)容提供者方式(ContentProvider)進(jìn)行存儲(chǔ)的方法
這篇文章主要介紹了Android編程使用內(nèi)容提供者方式進(jìn)行存儲(chǔ)的方法,涉及Android內(nèi)容提供者的創(chuàng)建,配置及針對(duì)數(shù)據(jù)的增刪改查等操作技巧,需要的朋友可以參考下2016-01-01Android 添加TextView刪除線(代碼簡(jiǎn)單)
最近接了個(gè)項(xiàng)目,其中有項(xiàng)目需求是這樣的,有這么個(gè)需求,就是一個(gè)產(chǎn)品下有兩個(gè)價(jià)格,一個(gè)是市場(chǎng)價(jià),一個(gè)是銷售價(jià),這時(shí)要把市場(chǎng)價(jià)添加個(gè)刪除線;怎么實(shí)現(xiàn)呢?下面小編給大家分享一段簡(jiǎn)單的代碼實(shí)現(xiàn)Android 添加TextView刪除線2016-02-02