Android+Flutter實(shí)現(xiàn)文字跑馬燈特效
跑馬燈被運(yùn)用在很多領(lǐng)域, 例如商場的電子條幅、大樓的宣傳廣告位、地鐵的廣告位.不過毫無疑問的是它們都是為了解決文字過長的問題而應(yīng)景給出的一種解決方案.
今天我們來說一下flutter 怎么通過繪制來實(shí)現(xiàn)跑馬燈效果! 等不及想看源碼的兄弟們,請走這里:https://github.com/weniner/flutter_demo/blob/main/lib/text_effects/widget/marquee_effect.dart
分析實(shí)現(xiàn)
我們都知道跑馬燈是不停的往前跑. 在給定的區(qū)域里,如果是最小的繪制區(qū)域,我們也至少繪制出它左邊剛出頭,右邊剛出尾的所有子項.同時我們也需要一個東西來驅(qū)動它去前行.
同時,文字也會有很多情況.
它可能很短,也可能和給定的的區(qū)域相等,也可能遠(yuǎn)超我們給定的區(qū)域. 在這種情況下,我們應(yīng)該首先獲取文字的寬度.然后確定每秒它會移動多少.并且還需要一個驅(qū)動器來驅(qū)動它去做這些變化.
測量文字
如果大家寫過Flutter, 一定用過Text Widget. 既然Text Widget 可以根據(jù)文字大小來展示,說明Flutter中是有一個api可以測量文字長寬的.這里直接給出答案:
// 我們最終繪制的文字 final String kText = 'Flutter 文字特效之跑馬燈'; { // 需要被測量的文字 Widget TextSpan measureText = TextSpan(text: kText, style: const TextStyle(color: Colors.black)); TextPainter _painter = TextPainter( text: measureText, textDirection: TextDirection.ltr, // 這里定義最大為1行 maxLines: 1, // 這里給定文字繪制的約束最小為0.0, 最大不限制.從而獲取真實(shí)的文字寬高 )..layout(minWidth: 0.0, maxWidth: double.infinity); }
其中,TextPainter便包含了我們需要的文字寬高.我們創(chuàng)建一個對象去保存這個信息,方便 后面去繪制.
// 這里繼承里ChangeNotifier, 可以讓我們以最小的代價刷新界面 class _TextInfo extends ChangeNotifier { // 繪制時最前面的文字偏移 double head = 0.0; double width; double margin; _TextInfo(this.width, this.margin); // speed是我們定義的偏移速度, // 這里與我們的偏移量息息相關(guān) void update(double speed) { // 首先先讓偏移量自減 head -= speed; // 如果超過了文字大小和間距的總長度,說明當(dāng)前的文字已經(jīng)超出了屏幕. // 我們應(yīng)該用緊接著下一條數(shù)據(jù)的偏移量賦值. if (head < -width - margin) { head += width + margin; } notifyListeners(); } }
動畫為媒
文字測量完后, 我們還需要一個可以驅(qū)動文字移動的驅(qū)動器. 這里你可以通過ticker自己實(shí)現(xiàn)一個驅(qū)動. 我們?yōu)榱撕唵位紤], 沒錯~ 我們又要請出我們的好兄弟AnimationController重出江湖了
實(shí)際上這里運(yùn)用不了太多AnimationController的參數(shù),我們唯一需要在乎的就是Duration, 也就是時間越短.我們將跑的越快.時間越長,跑的越慢.可以說是反比關(guān)系.
{ AnimationController _scrollController = AnimationController(vsync: this, duration: const Duration(seconds:1)); }
最終繪制
萬事俱備,只欠東風(fēng). 像一個方程, 我們所有的未知數(shù)都有了解. 只剩下最后求y了. 這里我們通過CustomPainter來繪制文字. 我們之前通過創(chuàng)建自己的類保存了文字信息,同時讓它繼承了ChangeNotifier就是為了今朝.
_RevolvingLanternPainter( this.painter, this.textInfo, ) : super(repaint: textInfo);
我們將CustomPainter的repaint參數(shù)賦值成我們自己定義的類. 每次我們update() 都會通知界面來刷新,從而不會影響別的界面, 只影響當(dāng)前的繪制畫布. 然后, 我們就可以去真正的繪制啦~ 這里我們唯一需要做的,就是給一個值x記錄下所有文字的偏移量. 如果偏移量大于當(dāng)前的界面. 說明它不在界面上, 也就不用繪制啦!
@override void paint(Canvas canvas, Size size) { double x = textInfo.head; while (x < size.width) { painter.paint(canvas, Offset(x, 0.0)); x += textInfo.width + textInfo.margin; } }
通過這種方法, 我們實(shí)現(xiàn)了跑馬燈文字的繪制~~
源碼:https://github.com/weniner/flutter_demo/blob/main/lib/text_effects/widget/marquee_effect.dart
到此這篇關(guān)于Android+Flutter實(shí)現(xiàn)文字跑馬燈特效的文章就介紹到這了,更多相關(guān)Android Flutter文字跑馬燈內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android中使用GridLayout網(wǎng)格布局來制作簡單的計算器App
這篇文章主要介紹了Android中使用GridLayout網(wǎng)格布局來制作簡單的計算器App的實(shí)例,GridLayout比表格布局TabelLayout更容易用來制作計算器這樣的多按鈕排列的界面,需要的朋友可以參考下2016-04-04Android通過原生APi獲取所在位置的經(jīng)緯度
本篇文章主要介紹了Android通過原生APi獲取所在位置的經(jīng)緯度,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07Input系統(tǒng)截斷策略的分析與應(yīng)用詳解
這篇文章主要為大家介紹了Input系統(tǒng)截斷策略的分析與應(yīng)用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02Android獲取SDcard目錄及創(chuàng)建文件夾的方法
今天小編就為大家分享一篇Android獲取SDcard目錄及創(chuàng)建文件夾的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08Android中通過Notification&NotificationManager實(shí)現(xiàn)消息通知
關(guān)于通知Notification相信大家都不陌生了,平時上QQ的時候有消息來了或者有收到了短信,手機(jī)頂部就會顯示有新消息什么的,就類似這種。今天就稍微記錄下幾種Notification的用法。3.0以前的通知和3.0以后的通知是有些區(qū)別的。2015-10-10