Flutter 组件封装:文字折叠 NExpandText

一、需求来源

开发时遇到一个需求需要在文字超过一行时有展开和收起菜单,效果如下:

20230601193625.jpg

二、使用示例

Header.h4(title: "字符串不够一行时"),
Container(
  color: Colors.yellowAccent,
  padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
  child: NExpandText(
    text: text.substring(0, 20),
    textStyle: textStyle,
    expandTitleStyle: TextStyle(color: Colors.green)
  ),
),
Header.h4(title: "字符串超过一行时(折叠)"),
Container(
  color: Colors.yellow,
  padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
  child: NExpandText(
    text: text,
    textStyle: textStyle,
    expandTitleStyle: TextStyle(color: Colors.green)
  ),
),
Header.h4(title: "字符串超过一行时(展开)"),
Container(
  color: Colors.yellow,
  padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
  child: NExpandText(
      text: text,
      textStyle: textStyle,
      expandTitleStyle: TextStyle(color: Colors.green)
  ),
),

三、组件源码



import 'package:flutter/material.dart';
import 'package:flutter_templet_project/extension/text_painter_ext.dart';

///如果文字超过一行,右边有展开收起按钮
class NExpandText extends StatefulWidget {

  NExpandText({
    Key? key,
    required this.text,
    required this.textStyle,
    this.expandMaxLine = 10,
    this.expandTitleStyle,
    this.initiallyExpanded = false,
  }) : super(key: key);


  /// 字符串
  String text;
  
  /// 字符串样式
  TextStyle textStyle;
  
  /// 超过一行初始展开状态
  bool initiallyExpanded;
  
  /// 展开状态最大行
  int expandMaxLine;
  
  /// 展开按钮文字样式
  TextStyle? expandTitleStyle;
  

  @override
  _NExpandTextState createState() => _NExpandTextState();
}

class _NExpandTextState extends State<NExpandText> {


  @override
  Widget build(BuildContext context) {

    return buildText(
      text: widget.text,
      textStyle: widget.textStyle,
      isExpand: widget.initiallyExpanded,
      expandMaxLine: widget.expandMaxLine,
      expandTitleStyle: widget.expandTitleStyle,
    );
  }

  buildText({
    required String text,
    required TextStyle textStyle,
    bool isExpand = false,
    int expandMaxLine = 10,
    TextStyle? expandTitleStyle,
  }) {
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints){

        final textPainter = TextPainterExt.getTextPainter(
          text: text,
          textStyle: textStyle,
          maxLine: 100,
          maxWidth: constraints.maxWidth,
        );
        final numberOfLines = textPainter.computeLineMetrics().length;
        // debugPrint("numberOfLines:${numberOfLines}");

        return StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {

            final btnTitle = isExpand ? "收起" : "展开";
            return Row(
              crossAxisAlignment: CrossAxisAlignment.end,
              children: [
                Expanded(
                  child: Container(
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.all(Radius.circular(19))
                    ),
                    child: Container(
                      // color: Colors.green,
                      padding: EdgeInsets.symmetric(vertical: 8),
                      child: Text(text,
                        style: textStyle,
                        maxLines: isExpand ? expandMaxLine : 1,
                      ),
                    ),
                  ),
                ),
                if(numberOfLines > 1) TextButton(
                  style: TextButton.styleFrom(
                    padding: EdgeInsets.zero,
                    tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                    minimumSize: Size(50, 18),
                  ),
                  onPressed: (){
                    isExpand = !isExpand;
                    setState((){});
                  },
                  child: Text(btnTitle, style: expandTitleStyle,),
                ),
              ],
            );
          }
        );
      }
    );

  }
}

总结

核心是通过 TextPainter 布局后获取行数代码:

final numberOfLines = textPainter.computeLineMetrics().length;

然后做尺寸判断进行处理,目前最优的方法。

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
img
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓(文末还有ChatGPT机器人小福利哦,大家千万不要错过)

PS:群里还设有ChatGPT机器人,可以解答大家在工作上或者是技术上的问题
图片

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值