flutter文本展开收起

文章介绍了一个在Flutter中自定义的ExpandableText类,该类扩展了StatefulWidget,用于创建一个可以展开和收缩的文本控件。它接受文本、最大行数、样式和是否展开等参数,内部使用TextPainter来检测文本是否超过最大行数。当文本超出限制时,提供‘查看全部’和‘收起’的选项,点击切换显示状态。
摘要由CSDN通过智能技术生成
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

class ExpandableText extends StatefulWidget {
  final String text;

  final int maxLines;

  final TextStyle style;

  final bool expand;

  const ExpandableText(
      {Key key, this.text, this.maxLines, this.style, this.expand})
      : super(key: key);

  
  State<StatefulWidget> createState() {
    return _ExpandableTextState(text, maxLines, style, expand);
  }
}

class _ExpandableTextState extends State<ExpandableText> {
  final String text;
  final int maxLines;
  final TextStyle style;
  bool expand;

  _ExpandableTextState(this.text, this.maxLines, this.style, this.expand) {
    if (expand == null) {
      expand = false;
    }
  }

  
  Widget build(BuildContext context) {
    return LayoutBuilder(builder: (context, size) {
      final span = TextSpan(text: text ?? '', style: style);

      //通过TextPainter判断是否超过最大行数
      final tp = TextPainter(
          text: span, maxLines: maxLines, textDirection: TextDirection.ltr);
      tp.layout(maxWidth: size.maxWidth);

      if (tp.didExceedMaxLines) {
        final textSize = tp.size;
        final position = tp.getPositionForOffset(Offset(
          textSize.width - tp.width,
          textSize.height,
        ));
        // 默认endOffset = position.offset;但是这样导致查看全部两字有时会换行,故再减了16(由于减了16所以收起时的行数会与传入的maxLines对不上,比传入的少了一行)
        final endOffset = tp.getOffsetBefore(position.offset - 16);
        return RichText(
            overflow: TextOverflow.clip,
          text: TextSpan(
              text: expand?text
                  : text.substring(0, endOffset)+'...',
              style: TextStyle(
                  fontSize: style != null ? style.fontSize : null,
                  color: Colors.black),
            children: [
              TextSpan(
                text: expand ? '收起' : '查看全部',
                style: TextStyle(
                    fontSize: style != null ? style.fontSize : null,
                    color: JadeColors.blue_2),
                recognizer: TapGestureRecognizer()
                  ..onTap = () {
                    setState(() {
                      expand = !expand;
                    });
                  },
              )
            ])
        );
      } else {
        return Text(text ?? '', style: style);
      }
    });
  }
}

使用

ExpandableText(
  text: Utils().breakWord(S.current.experienceStationTipTwo),
  maxLines: 4,
  style:TextStyle(fontSize: setFontSize(30)),
  ),
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值