Flutter:缩小时防止换行文本

wir*_*uma 1 flutter flutter-layout

我有一个小部件:(HtmlWidget('<font size="200">Some Long Sentence Alright</font>')来自https://pub.dev/packages/flutter_widget_from_html_core的自定义小部件,但使用Text('Some Long Sentence Alright', style: TextStyle(fontSize: 200))有同样的问题)。

因为它又大又长,当显示在手机上时,它会换行为:

Some Long 
Sentence Alright
Run Code Online (Sandbox Code Playgroud)

有两种缩小规模的方法:

1. 缩放变换

Transform.scale(
  child: myWidget,
  scale: 0.5,
)
Run Code Online (Sandbox Code Playgroud)

这种方法的问题:

2. 装配盒

Container(
  child: FittedBox(child: myWidget),
  width: 300,
  height: 100,
)
Run Code Online (Sandbox Code Playgroud)

这种方法只有一个问题:我不知道预期的width/height.

myWidget 基本上,我想要一个可以根据比例缩小的小部件(如Transform.scale),但不包装内容(如FittedBox)。

我怎么做?

mrp*_*int 5

Transform部件将自己的约束传递给Text小部件,如果视口对于 200px 字体大小来说不够宽,它将在缩小绘制之前进行包装。请参阅此处的RenderTransform源代码:它扩展、使用默认值并且仅覆盖。RenderProxyBoxperformLayoutpaint

知道了这一点,您可以实现自己的RenderObject来转换约束(在布局期间)和画布(在绘画期间)。我在这里想出了一个简单的实现。如下所示:它适用于 x2、x4 和 x8 字体大小,并且没有“幻影边距”。

飞镖演示

最重要的部分在这里:


  @override
  void performLayout() {
    // ...

    // adjust the constraints width before performing child layout
    final childConstraints =
        constraints.copyWith(maxWidth: constraints.maxWidth / scale);

    // ...
  }

  @override
  void paint(PaintingContext context, Offset offset) {
    // scale down during painting to compensate
    layer = context.pushTransform(/* ... */);
  }
Run Code Online (Sandbox Code Playgroud)