flutter Text 文本 更多 和 收起 功能

11 篇文章 0 订阅
9 篇文章 0 订阅
本文档介绍了一个名为`TextSpanShow`的组件,它允许根据需求自定义收起和更多按钮的样式,并提供多个参数控制显示。组件能够智能判断文本是否超过最大行数并进行截断,支持点击展开和收起全文。示例代码展示了如何使用该组件以及其在空安全环境下的实现。
摘要由CSDN通过智能技术生成

组件化,封装为公共组件

收起和更多按钮的样式可以根据自己的需求来修改,提供了很多可先参数来控制。

非空


class TextSpanShow extends StatefulWidget {
  final String text;
  final Color colorTest;
  final Color ellipsisColorTest;
  final Color moreBackgroundTest;
  final Color moreContainerColor;
  final int mMaxLine;
  final bool showColor;
  final TextStyle styleText;
  final double textSpanWidth;
  final double textSpanHeight;
  const TextSpanShow(
    this.text, {
    Key key,
    this.colorTest = Colors.black,
    this.ellipsisColorTest,
    this.mMaxLine = 3, this.styleText, this.moreBackgroundTest, this.showColor, this.textSpanWidth, this.textSpanHeight, this.moreContainerColor,
  }) : super(key: key);

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

class _TextSpanShowState extends State<TextSpanShow> {
  bool mIsExpansion = false;




  @override
  Widget build(BuildContext context) {
    return Container(
      width: widget.textSpanWidth ?? null,
      height: widget.textSpanHeight ?? null,
      color: widget.moreContainerColor ?? null,
      child: richText(widget.text,),
    );
  }

  Widget richText(String _text) {
    if (IsExpansion(_text)) {
     //如果需要截断
      if (mIsExpansion) {
        return Stack(
          children: <Widget>[
            new Text(
              _text,
              textAlign: TextAlign.left,
              style:widget.styleText?? TextStyle(color: widget.colorTest),
            ),
            Positioned(
              right: 0,
              bottom: 0,
              child: Container(
                decoration: BoxDecoration(color: Colors.red),
                child: GestureDetector(
                  onTap: () {
                    _isShowText();
                  },
                  child: Text("收起<",
                      style: TextStyleFactory.styleSubtitle3(
                          context, 12, Colors.blue)),
                ),
              ),
            ),
          ],
        );
      } else {
        return Stack(
          children: <Widget>[
            Padding(
              padding: EdgeInsets.all(0),
              child: Text(
                _text,
                maxLines: widget.mMaxLine,
                textAlign: TextAlign.left,
                overflow: TextOverflow.ellipsis,
                style:widget.styleText?? TextStyle(color: widget.ellipsisColorTest??widget.colorTest),
              ),
            ),
            Positioned(
              right: 0,
              bottom: 0,
              child: Container(
                  color: widget.moreContainerColor??Color.fromARGB(255, 250, 250, 250),
                  child: Row(
                    children: [
                      Container(
                        child: Text(
                          "...  ",
                          style:widget.styleText?? TextStyle(color: widget.moreBackgroundTest),
                        ),
                      ),
                      GestureDetector(
                        child: Text("更多>",
                            style: TextStyleFactory.styleSubtitle3(
                                context, 12, Colors.blue)),
                        onTap: () {
                          _isShowText();
                        },
                      ),
                    ],
                  )),
            ),
          ],
        );
      }
    } else {
      return Text(
        _text,
        maxLines: widget.mMaxLine,
        textAlign: TextAlign.left,
        overflow: TextOverflow.ellipsis,
        style:widget.styleText?? TextStyle(color: Colors.black),
      );
    }
  }

  bool IsExpansion(String text) {
    TextPainter _textPainter = TextPainter(
        maxLines: widget.mMaxLine,
        text: TextSpan(
            text: text, style: TextStyle(fontSize: 16.0, color: Colors.black)),
        textDirection: TextDirection.ltr)
      ..layout(maxWidth: Screen.width, minWidth: Screen.width);
    if (_textPainter.didExceedMaxLines) {
      //这里判断 文本是否截断
      return true;
    } else {
      return false;
    }
  }

  void _isShowText() {
    if (mIsExpansion) {
      //关闭了
      setState(() {
        mIsExpansion = false;
      });
    } else {
      setState(() {
        mIsExpansion = true;
      });
    }
  }
}

空安全


class TextSpanShow extends StatefulWidget {
  final String text;
  final Color? colorTest;
  final Color? ellipsisColorTest;
  final Color? moreBackgroundTest;
  final Color? moreContainerColor;
  final int mMaxLine;
  final bool? showColor;
  final TextStyle? styleText;
  final double? textSpanWidth;
  final double? textSpanHeight;

  const TextSpanShow(this.text,
      {super.key,
      required this.mMaxLine,
      this.colorTest,
      this.ellipsisColorTest,
      this.moreBackgroundTest,
      this.moreContainerColor,
      this.showColor,
      this.styleText,
      this.textSpanWidth,
      this.textSpanHeight});

  @override
  State<TextSpanShow> createState() => _TextSpanShowState();
}

class _TextSpanShowState extends State<TextSpanShow> {
  bool mIsExpansion = false;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: widget.textSpanWidth,
      height: widget.textSpanHeight,
      color: widget.moreContainerColor,
      child: richText(
        widget.text,
      ),
    );
  }

  Widget richText(String text) {
    if (isExpansion(text)) {
      //如果需要截断
      if (mIsExpansion) {
        return Row(
          crossAxisAlignment: CrossAxisAlignment.end,
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Expanded(
                child: Text(
              text,
               maxLines: 100,
              textAlign: TextAlign.left,
              style: widget.styleText ?? TextStyle(color: widget.colorTest),
            )),
            GestureDetector(
              behavior: HitTestBehavior.opaque,
              onTap: () {
                _isShowText();
              },
              child: Container(
                alignment: Alignment.bottomRight,
                width: 70.rpx,
                height: 30.rpx,
                child: const Icon(Icons.keyboard_arrow_up),
              ),
            ),
          ],
        );
      } else {
        return Row(
          crossAxisAlignment: CrossAxisAlignment.end,
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Expanded(
                child: Text(
              text,
              maxLines: widget.mMaxLine,
              textAlign: TextAlign.left,
              overflow: TextOverflow.ellipsis,
              style: widget.styleText ??
                  TextStyle(
                      color: widget.ellipsisColorTest ?? widget.colorTest),
            )),
            GestureDetector(
              behavior: HitTestBehavior.opaque,
              onTap: () {
                _isShowText();
              },
              child: Container(
                alignment: Alignment.bottomRight,
                width: 70.rpx,
                height: 30.rpx,
                child: const Icon(Icons.keyboard_arrow_down),
              ),
            ),
          ],
        );
      }
    } else {
      return Text(
        text,
        maxLines: widget.mMaxLine,
        textAlign: TextAlign.left,
        overflow: TextOverflow.ellipsis,
        style: widget.styleText ?? const TextStyle(color: Colors.black),
      );
    }
  }

  bool isExpansion(String text) {
    TextPainter textPainter = TextPainter(
        maxLines: widget.mMaxLine,
        text: TextSpan(
            text: text,
            style: const TextStyle(fontSize: 16.0, color: Colors.black)),
        textDirection: TextDirection.ltr)
      ..layout(maxWidth: 750.rpx, minWidth: 750.rpx);
    if (textPainter.didExceedMaxLines) {
      //这里判断 文本是否截断
      return true;
    } else {
      return false;
    }
  }

  void _isShowText() {
    if (mIsExpansion) {
      //关闭了
      setState(() {
        mIsExpansion = false;
      });
    } else {
      setState(() {
        mIsExpansion = true;
      });
    }
  }
}

使用


TextSpanShow(
          "t", mMaxLine: 3)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值