1. 程式人生 > 其它 >【Flutter造輪子】Text元件顯示指定行文字,若有超出加...點選檢視更多

【Flutter造輪子】Text元件顯示指定行文字,若有超出加...點選檢視更多

技術標籤:Flutter

樣例
效果如上圖,如果超出,顯示“…點選檢視更多”,正好湊夠4行,再新增一個字便超出4行。
原理: 使用TextPainter逐漸新增字嘗試,該元件超出的話,其屬性didExceedMaxLines為true
程式碼如下:

///文字超出一定行,自動隱藏,並新增入"...檢視更多詳情"為它設定點選事件
class HideText extends StatefulWidget {

   HideText({
      @required this.text, //正常字
      this.style,		//正常字樣式
      @required
this.additionText, //附加字,如點選檢視更多 this.additionStyle, //附加字的樣式 this.maxLines = 3, //行數,不傳 預設為3 this.additionUrl, //點選附加字跳轉URL this.additionParams, //點選附加字跳轉時攜帶的引數 }) : assert(text != null), assert(additionText != null); final String text; final TextStyle style;
final String additionText; final TextStyle additionStyle; final int maxLines; final String additionUrl; final Map<String, dynamic> additionParams; @override _HideTextState createState() => _HideTextState(); } class _HideTextState extends State<HideText> { @override Widget build
(BuildContext context) { return Container( padding: EdgeInsets.only(top: 10), child: _textPaint([TextSpan(text: widget.text, style : widget.style)]).didExceedMaxLines ? RichText( text: TextSpan( children: [ TextSpan( text: "${widget.text.substring(0, _fontNum())}", style: widget.style, ), TextSpan( children: [ TextSpan(text: "...", style: widget.style), TextSpan(text: "${widget.additionText}", style: widget.additionStyle) ], recognizer: TapGestureRecognizer() ..onTap = (){ if(isNotBlank(widget.additionUrl)) { FlutterBoost.singleton.open(widget.additionUrl); } } ) ] ), ) : Container( //未超出指定行數的話全部顯示 child: Text( widget.text, style: widget.style, ), ), ); } TextPainter _textPaint(List<InlineSpan> children){ return TextPainter( maxLines: widget.maxLines, text: TextSpan( children: children ), textDirection: TextDirection.ltr) ..layout(maxWidth: UIUtils.screenWidth(context) - 40); //若新功能寬度不一致,可嘗試修改, //UIUtils.screenWidth(context)是自定義的獲取螢幕寬度的方法 } int _fontNum(){ //計算最多可容納正常字的數目,可優化 int num = 0; int skip = 1; while(true){ bool isExceed = widget.text.length < num + skip || _textPaint([TextSpan(text: widget.text.substring(0, num + skip) + "...", style: widget.style), TextSpan(text: widget.additionText, style: widget.additionStyle)]).didExceedMaxLines; if(!isExceed) { num = num + skip; skip *= 2; continue; } if(isExceed && skip == 1){ return num; } skip = skip ~/ 2; } } }

在此基礎上可以根據需求改造,如點選檢視更多顯示所有內容等功能,不做贅述。