flutter 文字的展开以及收起

本文介绍了一个基于Flutter的自定义组件实现方案,该组件能够处理文本的展开与折叠功能,并通过计算文本的偏移量来确定显示的文本部分。文章详细展示了如何使用TextPainter等API来获取文本的最大行数位置,以及如何根据用户的点击事件切换文本的显示状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// 思路: 获取最大行数的尾部的偏移量。

  // 2. 在偏移量的尾部截图 展开或者收起的文字的大小

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:merchant/config.dart';

class OtherExpandableText extends StatefulWidget {
  final String? text;
  final TextStyle? style;
  final int? maxLines;
  final String expandText;
  final String collapseText;

  const OtherExpandableText(
      {Key? key,
      this.text,
      this.style,
      this.maxLines,
      required this.collapseText,
      required this.expandText})
      : super(key: key);

  @override
  State<OtherExpandableText> createState() => _OtherExpandableTextState();
}

class _OtherExpandableTextState extends State<OtherExpandableText> {
  bool expand = false;
  String linkText = "";
  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
        builder: (BuildContext context, BoxConstraints constraints) {
      // 思路: 获取最大行数的尾部的偏移量。
      // 2. 在偏移量的尾部截图 展开或者收起的文字的大小
      //第二种:
      var span = TextSpan(text: widget.text, style: widget.style);
      var textPainer = TextPainter(
          text: span,
          maxLines: widget.maxLines,
          textDirection: TextDirection.ltr);
      textPainer.layout(maxWidth: constraints.maxWidth);
      final textSize = textPainer.size;

      var position = textPainer.getPositionForOffset(Offset(
        textSize.width,
        textSize.height,
      ));

      final endOffset = textPainer.getOffsetBefore(position.offset);

      // if (textPainter.didExceedMaxLines) {
      //超出
      return RichText(
        // maxLines: expand ? null : widget.maxLines,
        text: TextSpan(
            text: expand
                ? widget.text
                : widget.text!.substring(
                    0,
                    //  endOffset
                    (endOffset! -
                        (expand
                            ? widget.collapseText.length - 1
                            : widget.expandText.length - 1))),
            style: TextStyle(
              overflow: TextOverflow.ellipsis,
              color: Config.secondTextColor,
              fontWeight: FontWeight.w500,
            ),
            children: [
              TextSpan(
                  text: expand ? widget.collapseText : widget.expandText,
                  style: TextStyle(
                    color: Config.primaryTextColor,
                    fontWeight: FontWeight.w500,
                    fontSize: 28.rpx,
                  ),
                  recognizer: TapGestureRecognizer()
                    ..onTap = () {
                      print("展开");
                      setState(() {
                        expand = !expand;
                      });
                    }),
            ]),
      );
      // } else {
      //   return Text(widget.text ?? "");
      // }
    });
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值