Flutter 32: 圖解 TextPainter 與 TextSp
RichText 富文字核心即 TextSpan,而 TextSpan 結構很像 Android 中的 ViewGroup 樹型結構。
TextSpan 樹形結構.png
RichText 日常用法
小菜理解為 RichText 是進階版的 Text,如下直接看例項:
TextDirection 用來控制文字位置,居左或居右邊;當與 TextAlign 屬性共存時,優先看整體,以 TextAlign 為準;
Widget richTextWid01() { return RichText( text: TextSpan( text: 'TextDirection.ltr 文字預設居左', style: TextStyle(fontSize: 16.0, color: Colors.black)), textDirection: TextDirection.ltr); }Widget richTextWid02() { return RichText( text: TextSpan( text: 'TextDirection.rtl 文字預設居右', style: TextStyle(fontSize: 16.0, color: Colors.black)), textDirection: TextDirection.rtl); }Widget richTextWid03() { return RichText( text: TextSpan( text: 'textDirection 與 textAlign 同時設定,優先看整體,文字居中', style: TextStyle(fontSize: 16.0, color: Colors.black)), textDirection: TextDirection.rtl, textAlign: TextAlign.center); }
RichText 可以藉助 TextSpan 實現文字的多種效果,小菜認為有點像文字效果拼接,每個 TextSpan 可以設定單獨效果;
Widget richTextWid04() { return RichText( text: TextSpan( text: '多種樣式,如:', style: TextStyle(fontSize: 16.0, color: Colors.black), children: <TextSpan>[ TextSpan( text: '紅色', style: TextStyle(fontSize: 18.0, color: Colors.red)), TextSpan( text: '綠色', style: TextStyle(fontSize: 18.0, color: Colors.green)), TextSpan( text: '藍色', style: TextStyle(fontSize: 18.0, color: Colors.blue)), TextSpan( text: '白色', style: TextStyle(fontSize: 18.0, color: Colors.white)), TextSpan( text: '紫色', style: TextStyle(fontSize: 18.0, color: Colors.purple)), TextSpan( text: '黑色', style: TextStyle(fontSize: 18.0, color: Colors.black)) ]), textAlign: TextAlign.center); }
TextSpan 可以藉助 recognizer 設定點選事件,包括點選/長按等;
final TapGestureRecognizer recognizer = TapGestureRecognizer();void initState() { super.initState(); recognizer.onTap = () { Toast.show('您好,歡迎點贊或關注!', context, duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM); }; }Widget richTextWid05() { return RichText( text: TextSpan( text: 'recognizer 為手勢識別者,可設定點選事件,', style: TextStyle(fontSize: 17.0, color: Colors.black), children: <TextSpan>[ TextSpan( text: '點我試試', style: TextStyle(fontSize: 17.0, color: Colors.blue), recognizer: recognizer) ])); }
TextPainter 日常用法
RichText 的使用很方便,但如果在深入瞭解 TextSpan 就有很多趣味了;Flutter 提供了和 Android 類似的 Canvas 繪製方法,但是 Canvas 卻不支援 drawText,如果想要實現繪製文字,就需要 而其內部主要是由 TextSpan 實現。
使用 TextPainter 時需要繼承 CustomPainter,並實現 paint 和 shouldRepaint 方法,主要是在 paint 中進行繪製 TextPainter。與 RichText 功能相同,可以完全實現 RichText 效果;
TextPainter 繪製需要實現 layout 與 paint 方法,即繪製位置與繪製範圍。
TextDirection 和 TextAlign 效果與 RichText 一致,但是 TextPainter 繪製時需要設定 layout 的最大最小範圍,而此時,文字位置與 layout 有關;當文字長度小於設定的 minWidth 最小寬度時,以 minWidth 寬度為限制居左/居右/居中等;而當文字長度大於設定的 minWidth 最小寬度時,以 maxWidth 最大寬度為限制,包括換行等;
TextPainter( text: TextSpan( text: 'TextDirection.ltr 文字預設居左', style: TextStyle(fontSize: 16.0, color: Colors.black)), textDirection: TextDirection.ltr) ..layout(maxWidth: Screen.width, minWidth: Screen.width) ..paint(canvas, Offset(0.0, 0.0)); TextPainter( text: TextSpan( text: 'TextDirection.rtl 文字預設居右', style: TextStyle(fontSize: 16.0, color: Colors.black)), textDirection: TextDirection.rtl) ..layout(maxWidth: Screen.width, minWidth: Screen.width) ..paint(canvas, Offset(0.0, 24.0)); TextPainter( text: TextSpan( text: 'textDirection 與 textAlign 同時設定,優先看整體,文字居中', style: TextStyle(fontSize: 16.0, color: Colors.black)), textDirection: TextDirection.rtl, textAlign: TextAlign.center) ..layout(maxWidth: Screen.width, minWidth: Screen.width) ..paint(canvas, Offset(0.0, 48.0)); TextPainter( text: TextSpan( text: '文字位置與 layout 的最大最小寬度有關', style: TextStyle(fontSize: 16.0, color: Colors.black)), textDirection: TextDirection.rtl) ..layout(maxWidth: Screen.width - 100.0, minWidth: Screen.width - 200.0) ..paint(canvas, Offset(0.0, 90.0)); TextPainter( text: TextSpan( text: '文字長度較小', style: TextStyle(fontSize: 16.0, color: Colors.black)), textDirection: TextDirection.rtl) ..layout(maxWidth: Screen.width - 100.0, minWidth: Screen.width - 140.0) ..paint(canvas, Offset(0.0, 124.0));
而對於繪製多效果的樣式也是很方便,與 RichText 基本一致;
TextPainter( text: TextSpan( text: '多種樣式,如:', style: TextStyle(fontSize: 16.0, color: Colors.black), children: <TextSpan>[ TextSpan( text: '紅色', style: TextStyle(fontSize: 18.0, color: Colors.red)), TextSpan( text: '綠色', style: TextStyle(fontSize: 18.0, color: Colors.green)), TextSpan( text: '藍色', style: TextStyle(fontSize: 18.0, color: Colors.blue)), TextSpan( text: '白色', style: TextStyle(fontSize: 18.0, color: Colors.white)), TextSpan( text: 'n紫色', style: TextStyle(fontSize: 18.0, color: Colors.purple)), TextSpan( text: '黑色', style: TextStyle(fontSize: 18.0, color: Colors.black)) ]), textDirection: TextDirection.ltr, textAlign: TextAlign.center) ..layout(maxWidth: Screen.width, minWidth: Screen.width) ..paint(canvas, Offset(0.0, 148.0));
小菜一直有問題的就是設定點選事件,小菜以為與 RichText 一樣直接傳遞 recognizer 即可,但始終無法調起,希望有解決過這個問題的朋友多多指導,如下是小菜的測試程式碼;
TextPainter( text: TextSpan( text: 'recognizer 為手勢識別者,可設定點選事件,', style: TextStyle(fontSize: 17.0, color: Colors.black), children: <TextSpan>[ TextSpan( text: '測試暫時有誤,待研究', style: TextStyle(fontSize: 17.0, color: Colors.blue)) ], recognizer: TapGestureRecognizer() ..onTap = () { print('===測試暫時有誤,待研究=='); }), textDirection: TextDirection.ltr, textAlign: TextAlign.center) ..layout(maxWidth: Screen.width - 40.0, minWidth: Screen.width - 40.0) ..paint(canvas, Offset(20.0, 200.0));
小菜認為最有意思的就是 TextSpan 中 style 的 height 屬性,在 TextSpan 中此值設定行高,是以文字基準線為最小距離;
TextPainter( text: TextSpan( text: 'TextPainter 小嚐試', style: TextStyle(fontSize: 20.0, color: Colors.black54), children: <TextSpan>[ TextSpan( text: 'n作者:和尚(height:1.6)', style: TextStyle( fontSize: 14.0, color: Colors.black54, height: 1.6)) ]), textDirection: TextDirection.ltr, textAlign: TextAlign.center) ..layout(maxWidth: Screen.width, minWidth: Screen.width) ..paint(canvas, Offset(0.0, 20.0)); TextPainter( text: TextSpan( text: 'TextPainter 小嚐試', style: TextStyle(fontSize: 20.0, color: Colors.black54), children: <TextSpan>[ TextSpan( text: 'n作者:和尚(height:3.0)', style: TextStyle( fontSize: 14.0, color: Colors.black54, height: 3.0)) ]), textDirection: TextDirection.ltr, textAlign: TextAlign.center) ..layout(maxWidth: Screen.width, minWidth: Screen.width) ..paint(canvas, Offset(0.0, 90.0)); TextPainter( text: TextSpan( text: 'TextPainter 小嚐試(height:0.1)', style: TextStyle(fontSize: 20.0, color: Colors.black54, height: 0.1), children: <TextSpan>[ TextSpan( text: 'nTextPainter 小嚐試(height:0.1)', style: TextStyle( fontSize: 20.0, color: Colors.black54, height: 0.1)), TextSpan( text: 'nTextPainter 小嚐試(height:0.1)', style: TextStyle( fontSize: 20.0, color: Colors.black54, height: 0.1)) ]), textDirection: TextDirection.ltr, textAlign: TextAlign.center) ..layout(maxWidth: Screen.width, minWidth: Screen.width) ..paint(canvas, Offset(0.0, 220.0));
作者:阿策神奇
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4662/viewspace-2822124/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Flutter 58: 圖解 Flutter 嵌入原生 AndroidFlutter圖解Android
- Flutter載入圖片與GlideFlutterIDE
- 圖解Flutter——BLoC的原理及使用圖解FlutterBloC
- Flutter 74: 圖解基本 DropdownButton 下拉選Flutter圖解
- Flutter 中的圖文混排與原理解析Flutter
- Flutter 112: 圖解自定義 ACEPieWidget 餅狀圖Flutter圖解
- Flutter快坑我:圖解環境搭建(windows)Flutter圖解Windows
- Flutter 38: 圖解 Android 打包 APK 檔案Flutter圖解AndroidAPK
- Flutter非同步與執行緒詳解Flutter非同步執行緒
- Flutter學習筆記(32)--PointerEvent事件處理Flutter筆記事件
- 圖解Flutter建立Isolate的過程及通訊圖解Flutter
- Flutter 45: 圖解矩陣變換 Transform 類 (二)Flutter圖解矩陣ORM
- Flutter 125: 圖解自傳 ACE_ICON.ttf 圖示庫Flutter圖解
- Flutter 篇 輪播圖 flutter_swiperFlutter
- Flutter輪播圖Flutter
- Flutter 生成圖片Flutter
- Flutter 115: 圖解自定義 View 之 Canvas (四Flutter圖解ViewCanvas
- Flutter 23: 圖解自定義 Dialog 對話方塊Flutter圖解
- Flutter 47: 圖解新的狀態管理 Provider (二)Flutter圖解IDE
- 【Flutter 專題】96 圖解 Draggable + DragTarget 基本拖拽效果Flutter圖解
- Flutter與原生通訊 - Flutter PluginFlutterPlugin
- 29.Flutter與原生解耦式混合開發Flutter解耦
- 解讀 Flutter 全平臺開發的誤解與偏見Flutter
- 拼圖遊戲 (32千字)遊戲
- 【Flutter 專題】58 圖解 Flutter 嵌入原生 AndroidView 小嚐試|8月更文挑戰Flutter圖解AndroidView
- 【Flutter 專題】63 圖解 Flutter 整合極光 JPush 小結|8月更文挑戰Flutter圖解
- Flutter 圖片載入Flutter
- Flutter 圖片全家桶Flutter
- Flutter 圖片的使用Flutter
- 【Flutter 專題】125 圖解自傳 ACE_ICON.ttf 圖示庫Flutter圖解
- 【Flutter 專題】104 圖解自定義 ACEDropdownButton 下拉框Flutter圖解
- 【Flutter 專題】89 圖解基本 Overlay 懸浮新手引導Flutter圖解
- 圖解正向代理與反向代理圖解
- JS原型與原型鏈圖解JS原型圖解
- Flutter Gzip 編碼與解碼 Dart Gzip 工具類操作FlutterDart
- 32_分散式文件系統_document查詢內部原理圖解揭秘分散式圖解
- STM32--USART詳解
- 騰訊地圖Flutter業務實踐——地圖SDK Flutter外掛實現(一)地圖Flutter