第一种是行数判断:

项目需求是超过6行显示展开,超过12行跳到其他页面,所以我这样写,其中图片文字可随意改。
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'dart:ui';

class ExpandableText extends StatefulWidget {
  final String text;//文本
  final GestureTapCallback onJudgeClick;//跳转
  final int maxLines, maxlastLines;//7行限制,12行限制
  final TextStyle style;//样式
  final bool expand;//默认是否展开

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

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

class _ExpandableTextState extends State<ExpandableText> {
  bool expand = false;

  @override
  Widget build(BuildContext context) {
    String text = widget.text;
    GestureTapCallback onJudgeClick = widget.onJudgeClick;
    int maxLines = widget.maxLines, maxlastLines = widget.maxlastLines;
    final TextStyle style = widget.style;

    return LayoutBuilder(builder: (context, size) {
      final span = TextSpan(text: text ?? '', style: style);
      //tp是7行的,判断高度,判断xy轴的字符位置,tpmax是12行的,判断高度,判断12行的位置。
      final tp = TextPainter(text: span, maxLines: maxLines, textDirection: TextDirection.ltr);
      final tpmax = TextPainter(text: span, maxLines: maxlastLines, textDirection: TextDirection.ltr);
      tp.layout(maxWidth: size.maxWidth);
      tpmax.layout(maxWidth: size.maxWidth);

      TextPosition position = tp.getPositionForOffset(Offset(240, 200));

      TextPosition maxposition = tpmax.getPositionForOffset(Offset(240, 600));

      if (tp.didExceedMaxLines) {
        return Stack(
          children: <Widget>[
            expand
                ? (tpmax.didExceedMaxLines)
                    ? Text(text.substring(0, maxposition.offset) + '...', style: style)
                    : Text(text, style: style)
                : Text(text.substring(0, position.offset) + '...', style: style),
//这是之前默认展开收起的样式,现在改成只展开不收起
//            expand ? Text(text ?? '', style: style)
//                : Text(text ?? '', maxLines: maxLines, overflow: TextOverflow.ellipsis, style: style),
            Positioned(
              right: 0,
              bottom: 0,
              child: GestureDetector(
                behavior: HitTestBehavior.translucent,
                onTap: () {
                  if (expand) {
                    if (tpmax.didExceedMaxLines) {
                      //这里做点击事件判断 如果有新需求改动判断新建回调就可以了
                      onJudgeClick();
                    }
                  } else {
                    setState(() {
                      expand = !expand;
                    });
                  }
                },
                child: Container(
                  color: Colors.white,
                  padding: EdgeInsets.only(top: 2),
                  child: RichText(
                    text: TextSpan(
 //这是以前没有判断xy轴位置的省略号,现在不用了
 //                     text: expand ? (tpmax.didExceedMaxLines ? '... ' : '') : '',
 //                     style: TextStyle(color: Color(0xFF333333), fontSize: 15),
                      children: [
                        TextSpan(
                          text: expand ? (tpmax.didExceedMaxLines ? '查看全文' : '') : '展开更多',
                          style: TextStyle(color: Color(0xFF28C6A8), fontSize: 15),
                        ),
                        WidgetSpan(
                          alignment: PlaceholderAlignment.middle,
                          child: expand
                              ? (tpmax.didExceedMaxLines
                                  ? Padding(
                                      padding: const EdgeInsets.all(5.0),
                                      child: SizedBox(
                                          width: 9,
                                          height: 4.5,
                                          child: Transform.rotate(
                                            child: Image.asset('assets/images/common/lujing.png'),
                                            angle: 0,
                                          )),
                                    )
                                  : Container())
                              : Padding(
                                  padding: const EdgeInsets.all(5.0),
                                  child: SizedBox(
                                      width: 9,
                                      height: 4.5,
                                      child: Transform.rotate(
                                        child: Image.asset('assets/images/common/lujing.png'),
                                        angle: 0,
                                      )),
                                ),
                        ),
                      ],
                    ),
                  ),
                ),
              ),
            )
          ],
        );
      } else {
        return Text(text ?? '', style: style);
      }
    });
  }
}

第二种是字数判断:

这个是超过80字,使用效果不太好。但是很简单

///展示全文查看全文字数text
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

class ExpandableCountText extends StatefulWidget {
  final String text;

  final int maxLines;

  const ExpandableCountText({
    Key key,
    this.text,
    this.maxLines = 80,
  }) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return _ExpandableTextlenState();
  }
}

class _ExpandableTextlenState extends State<ExpandableCountText> {
  String _text;

  int _maxLines;

  bool _showMore = false;
  bool _isExpended = false;
  TapGestureRecognizer _tapGestureRecognizer = TapGestureRecognizer();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _text = widget.text;
    _maxLines = widget.maxLines;
    if (_text.length > _maxLines) {
      _showMore = true;
      _isExpended = false;
    } else {
      _showMore = false;
      _isExpended = true;
    }
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    _tapGestureRecognizer.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Text.rich(TextSpan(children: [
      TextSpan(text: _isExpended ? _text : _text.substring(0, _maxLines) + '...'),
      TextSpan(
          recognizer: _tapGestureRecognizer
            ..onTap = () {
              setState(() {
                _isExpended = !_isExpended;
              });
            },
          text: _showMore ? _isExpended ? '收起' : '展开' : '',
          style: TextStyle(color: Colors.green))
    ]));
  }
}
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐