如何在颤动中使文本与宽度允许的一样大

How to make text as big as the width allows in flutter

我有一个容器,我需要在其中显示条形码,我希望条形码在屏幕上尽可能宽。 现在我将字体大小设置为适合所有设备的合理大小,但这当然只是暂时的。 我该如何解决这个问题?这是我用于构建小部件的代码。

@override
Widget build(BuildContext context) {
  return Scaffold(
      appBar: AppBar(
      title: Text(_title),
    ),
    body: Container(
    padding: const EdgeInsets.all(12.0),
    child: Column(
      children: <Widget>[ 
        SizedBox(
          width: double.infinity,
          child: Text(_barcode, style: TextStyle(fontFamily: 'Code128', fontSize: 90.0))
        ),
        Text(_barcode, style: TextStyle(fontSize: 40.0))
        ]
      ),
    )
  );
}

我相信你要找的是FittedBox

BoxFit 应用您想要 stretch/scale child 的任何 'fit' 以适合框。它不会对文本执行纯 'stretch',而是它应该占用的 space。您不应该同时指定文本的大小。

看起来像这样:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  MyAppState createState() {
    return new MyAppState();
  }
}

class MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Center(
            child: Container(
              color: Colors.blue,
              width: 300.0,
              height: 200.0,
              child: FittedBox(
                fit: BoxFit.contain,
                child: Text("Whee"),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

如果您实际上想要 'stretch' 文本(即使实际字符变宽或变高),则必须做一些更自定义的事情。

如果是这样,请查看 CustomPaint, CustomPainter, TextPainter, and the Canvas translate & scale 选项。基本上,您需要创建一个 class 扩展 CustomPainter,您在其中创建了一个 TextPainter,将其布局为特定大小,将其绘制到 canvas 上,然后将其缩放以适合实际大小CustomPainter(或者你先缩放 canvas - 我忘记了......)。然后您将 class 的一个实例传递给 CustomPaint。

使用 TextPainter.width 和 for 循环找到最大的合适字体大小(添加 +1 不是很有效,您可能需要微调):

import 'package:flutter/material.dart';

main() => runApp(MaterialApp(
      home: MyHomePage(),
      theme: ThemeData(platform: TargetPlatform.iOS),
    ));

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Text autoscale'),
      ),
      body: Padding(
        padding: EdgeInsets.all(32.0),
        child: Center(
          child: LayoutBuilder(
            builder: (BuildContext context, BoxConstraints constraints) {
              final text = 'Hello World';
              final style = TextStyle(fontWeight: FontWeight.bold); // apply your barcode font here
              final fontSize = calculateAutoscaleFontSize(text, style, 30.0, constraints.maxWidth);
              return Text(
                text,
                style: style.copyWith(fontSize: fontSize),
                maxLines: 1,
              );
            },
          ),
        ),
      ),
    );
  }
}

double calculateAutoscaleFontSize(String text, TextStyle style, double startFontSize, double maxWidth) {
  final textPainter = TextPainter(textDirection: TextDirection.ltr);

  var currentFontSize = startFontSize;

  for (var i = 0; i < 100; i++) {
    // limit max iterations to 100
    final nextFontSize = currentFontSize + 1;
    final nextTextStyle = style.copyWith(fontSize: nextFontSize);
    textPainter.text = TextSpan(text: text, style: nextTextStyle);
    textPainter.layout();
    if (textPainter.width >= maxWidth) {
      break;
    } else {
      currentFontSize = nextFontSize;
      // continue iteration
    }
  }

  return currentFontSize;
}

您可以使用适合的盒子小部件。

FittedBox(child:Text('text sample'));

https://api.flutter.dev/flutter/widgets/FittedBox-class.html

将文本包裹在 FittedBox 小部件中,以强制将文本包含在一个框内。 FittedBox 的大小将取决于它的父窗口小部件。在 FittedBox 中,文本小部件可以简单地 'cover' 框,因此文本不会拉伸以填充 FittedBox 中可用的 space。枚举 BoxFit.fill 是一种拉伸文本以适应 FittedBox 中可用的整个 space 的方法。您可以通过更改 FittedBox 的父容器 Container 的高度和宽度来更改框的尺寸。

Container(
  height: _height,
  width: _width,
  FittedBox(               
    fit: BoxFit.fill,
    child: Text("Whee"),
  )
)

FittedBox 仅在提供一些限制条件下才有效,因此请确保提供一个限制条件,例如提供高度,如下所示:

SizedBox(
  height: 400, // 1st set height
  child: FittedBox(child: Text("*")), // 2nd wrap in FittedBox
)

FittedBox 对我有用,但有一个转折点。我还必须将我的 fontSize 设置为一个大数字才能正常工作。希望这有帮助。

child: FittedBox(
                  fit: BoxFit.fitHeight,
                  child: Text(
                    "Your Expanded Text :)",
                    style: TextStyle(fontSize: 400.0),
                  ),
                ),

问题中的代码示例有一个 Text 小部件作为 Column 小部件的 children: 之一。 Text 父级的宽度未知。

因此,为了在这种情况下最大化 Text 小部件的宽度和大小,请将 Text 小部件包装在 FittedBox 中,然后是 Expanded.

child: Column(children: <Widget>[
  Expanded(
    child: FittedBox(
        fit: BoxFit.contain,
        child: Text(
          '123',
        )),
  ),
]),

即使在旋转设备或调整屏幕大小时,Text 大小也应自动正确调整大小,而不会出现溢出问题。

展开:

/// A widget that expands a child of a [Row], [Column], or [Flex]
/// so that the child fills the available space.
///
/// Using an [Expanded] widget makes a child of a [Row], [Column], or [Flex]
/// expand to fill the available space along the main axis (e.g., horizontally for
/// a [Row] or vertically for a [Column]). If multiple children are expanded,
/// the available space is divided among them according to the [flex] factor.

来自 /flutter/packages/flutter/lib/src/widgets/basic.dart

装箱:

/// Creates a widget that scales and positions its child within itself according to [fit].