You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter如何实现文本上方透明容器及多行文本触发显示逻辑?

Flutter 实现文本多行渐变遮罩+行数判断方案

核心思路

不需要单独添加透明容器,用ShaderMask配合文本组件就能实现渐变遮罩效果;判断文本是否超过指定行数,借助TextPainter计算文本渲染后的实际行数即可。

具体实现步骤

1. 判断文本是否超过5行

通过TextPainter提前计算文本在给定宽度下的行数:

bool isTextOverflow(String text, TextStyle style, double maxWidth, int maxLines) {
  final textPainter = TextPainter(
    text: TextSpan(text: text, style: style),
    maxLines: maxLines,
    textDirection: TextDirection.ltr,
  )..layout(maxWidth: maxWidth);
  
  return textPainter.didExceedMaxLines;
}

调用这个方法就能知道文本是否超过5行,返回true时就显示渐变遮罩和展开按钮。

2. 实现带渐变遮罩的文本

用ShaderMask包裹Text组件,给底部添加渐变遮罩,仅在文本超出行数时启用遮罩:

Widget buildOverflowText(String text, TextStyle style, double width, bool isOverflow) {
  return ShaderMask(
    shaderCallback: (rect) {
      if (!isOverflow) {
        return const LinearGradient(
          colors: [Colors.black, Colors.black],
        ).createShader(rect);
      }
      return LinearGradient(
        begin: Alignment.topCenter,
        end: Alignment.bottomCenter,
        colors: [
          Colors.black,
          Colors.black.withOpacity(0.8),
          Colors.black.withOpacity(0.3),
          Colors.transparent,
        ],
        stops: const [0, 0.7, 0.9, 1],
      ).createShader(rect);
    },
    blendMode: BlendMode.dstIn,
    child: Text(
      text,
      style: style,
      maxLines: isOverflow ? 5 : null,
      overflow: TextOverflow.clip,
    ),
  );
}

3. 整合展开/收起逻辑(可选)

如果需要展开收起功能,维护一个bool _isExpanded状态变量,点击按钮切换状态来控制文本的maxLines:

bool _isExpanded = false;
bool _isOverflow = false;
late String _content;
late TextStyle _textStyle;
double _textWidth = 300; // 根据实际布局宽度调整

@override
void initState() {
  super.initState();
  _content = "你的长文本内容...";
  _textStyle = const TextStyle(fontSize: 14);
  _isOverflow = isTextOverflow(_content, _textStyle, _textWidth, 5);
}

@override
Widget build(BuildContext context) {
  return Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      SizedBox(
        width: _textWidth,
        child: buildOverflowText(
          _content,
          _textStyle,
          _textWidth,
          _isOverflow && !_isExpanded,
        ),
      ),
      if (_isOverflow)
        TextButton(
          onPressed: () {
            setState(() {
              _isExpanded = !_isExpanded;
            });
          },
          child: Text(_isExpanded ? "收起" : "查看更多"),
        ),
    ],
  );
}

关键说明

  • 无需单独添加透明容器:ShaderMask直接给文本添加渐变遮罩,比单独加容器更高效,避免额外布局层级。
  • 行数判断的核心:TextPainter的didExceedMaxLines属性,能准确判断文本在指定宽度和最大行数下是否溢出。

内容的提问来源于stack exchange,提问作者Riana Deana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 15:11:13