gpt4 book ai didi

使用 LineMetrics 获取文本高度的 flutter 问题

转载 作者:行者123 更新时间:2023-12-04 10:00:28 24 4
gpt4 key购买 nike

我有一个应用程序在背景图像前面显示带有文本的内容卡。为了更好的可读性,在文本和背景图像之间添加了一个模糊层。由于 flutter 在构建之前获取小部件(或文本)的高度并不容易,因此我能找到解决此问题的唯一方法(不使用回调或重绘)是 LineMetrics。使用 LineMetrics,我可以计算文本以正确大小绘制模糊层所需的空间。
现在问题来了:计算出的width LineMetrics 的属性有时不适合呈现的文本宽度。这在导致错过换行符的情况下是有问题的,因为模糊的背景不再覆盖整个文本区域。
Screenshot Text Fill
我在做什么:关注这个 medium article我首先创建一个带有文本和样式的 TextSpan,然后将其添加到 TextPainter,然后调用 layout()功能与 minWidth: 0 , 和 maxWidth: maxTextWidth .最后我用 textPainter.computeLineMetrics() 创建了 LineMetrics :

  // Widget
@override
Widget build(BuildContext context) {

// Get text styles
final TextStyle titleStyle = TextStyle(
fontFamily: 'SF Pro Display',
fontStyle: FontStyle.normal,
fontSize: 14,
height: (17 / 14),
fontWeight: FontWeight.bold,
color: Colors.white);
final TextStyle textStyle = TextStyle(
fontFamily: 'SF Pro Display',
fontStyle: FontStyle.normal,
fontSize: 14,
height: (17 / 14),
fontWeight: FontWeight.normal,
color: Colors.white);

// Build text spans
final titleSpan = TextSpan(text: title, style: titleStyle);
final textSpan = TextSpan(text: text, style: textStyle);

// Calculate text metrics
final double _maxWidth = style.width - style.margin.horizontal;
List<LineMetrics> _titleLines = _getLineMetrics(_maxWidth, titleSpan);
List<LineMetrics> _textLines = _getLineMetrics(_maxWidth, textSpan);

// Calculate text heights
final double _titleHeight = _getLinesHeight(_titleLines) + style.margin.top;
final double _textHeight = _getLinesHeight(_textLines) + style.margin.bottom;

// Generate coloured debug container
Column _titleContainer = _getTextSpanContainer(_titleLines);
Column _textContainer = _getTextSpanContainer(_textLines);

// Widget content
List<Widget> _textOverlay = [
Expanded(child: Text('')),
Stack(children: <Widget>[
Align(alignment: Alignment.topLeft, child: _titleContainer),
Align(alignment: Alignment.topLeft, child: RichText(text: titleSpan))
]),
Stack(children: <Widget>[
Align(alignment: Alignment.topLeft, child: _textContainer),
Align(alignment: Alignment.topLeft, child: RichText(text: textSpan))
])
];


List<LineMetrics> _getLineMetrics(double width, TextSpan textSpan) {
final textPainter = TextPainter(
text: textSpan,
textDirection: TextDirection.ltr
);

textPainter.layout(
minWidth: 0,
maxWidth: width,
);

// TODO: width of lineMetrics sometimes not matching real text width
return textPainter.computeLineMetrics();
}

double _getLinesHeight(List<LineMetrics> lines) {
double _textHeight = 0;

for (LineMetrics line in lines) {
_textHeight += line.height;
}

return _textHeight;
}

Column _getTextSpanContainer(List<LineMetrics> lines) {
List<Widget> container = [];

for (LineMetrics line in lines) {
container.add(Container(
width: line.width,
height: line.height,
color: Colors.red,
));
}

return Column(
children: container,
crossAxisAlignment: CrossAxisAlignment.start,
);
}
我在每个文本行后面添加了红色轮廓,并使用 LineMetrics 的计算宽度来可视化问题。大多数情况下它有效,但有时计算的宽度不匹配:
Screenshot Text Outline
我尝试了 TextStyles 中几乎所有可能的属性(WordSpacing、LetterSpacing、textWidthBasis...),使用和不使用自定义字体构建它,使用 RichText 和普通文本元素进行绘制,但所描述的问题没有任何变化。
任何人都可以帮助修复这种奇怪的行为,或者提供一种替代方法来在构建小部件之前获取文本高度?
一些相关问题:
  • How to get the raw text from a Flutter TextBox
  • What is the meaning Flutter's width metrics for the Paragraph class?
  • How can I get the size of the Text Widget in flutter
  • 最佳答案

    我不能说 textPainter.computeLineMetrics 的怪异行为你观察,但我认为你的问题有一个不同的解决方案,它不涉及测量文本小部件的高度。
    您的 content-cards可以使用 StackPositioned和一个 BackdropFilter ,您可以对其进行剪辑以适合覆盖的文本。
    这样做时,您无需费心测量 Text 小部件。
    例子:

    class MyWidget extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return Stack(
    fit: StackFit.expand,
    children: <Widget>[
    FittedBox(
    fit: BoxFit.fill,
    child: Image.network('https://picsum.photos/300'),
    ),
    Positioned(
    bottom: 0,
    left: 0,
    right: 0,
    child: ClipRect(
    child: BackdropFilter(
    filter: ImageFilter.blur(
    sigmaX: 3.0,
    sigmaY: 3.0,
    ),
    child: Padding(
    padding: const EdgeInsets.all(8.0),
    child: const Text(
    'Aut velit illum eos aut aut eaque totam. Autem aut quis omnis et minus. Itaque at molestias enim sunt autem voluptas voluptatem delectus. Minima deleniti fugiat sit sunt fugiat. Cumque iusto quo eum. Ipsa laborum est qui.'),
    ),
    ),
    ),
    ),
    ],
    );
    }
    }

    NOTE: This example renders an expanded Stack. For your content-cards, you would probably use e.g. a SizedBox to constrain its dimensions.


    此致

    关于使用 LineMetrics 获取文本高度的 flutter 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61843142/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com