Flutter 如何根据字符串长度确定容器的宽度?

Flutter 如何根据字符串长度确定容器的宽度?,flutter,pdf,Flutter,Pdf,我想让一个字段,一个带边框的容器更加明确,用于打印,但我希望它的宽度基于字符串的长度 例如,假设pdf应该有一个包含14个字符的代码字段。 如何使容器适合这14个字符 谢谢。请查看下面的代码,它显示了两种方法—(1)RenderBox和(2)TextPainter—获取文本宽度。你可以使用适合你的方法。RenderBox方法只能在生成后使用,因此在生成后使用WidgetsBinding addPostFrameCallback调用它 注1:此代码使用默认的TextStyle。如果使用不同的Tex

我想让一个字段,一个带边框的容器更加明确,用于打印,但我希望它的宽度基于字符串的长度

例如,假设pdf应该有一个包含14个字符的代码字段。 如何使容器适合这14个字符


谢谢。

请查看下面的代码,它显示了两种方法—(1)RenderBox和(2)TextPainter—获取文本宽度。你可以使用适合你的方法。RenderBox方法只能在生成后使用,因此在生成后使用WidgetsBinding addPostFrameCallback调用它

注1:此代码使用默认的TextStyle。如果使用不同的TextStyle,则必须在函数中传递该TextStyle

注2:您只要求输入文本宽度,因此此代码显示了如何获得文本宽度。您可以为您在PDF中绘制的容器提供适当的填充或边距

import 'package:flutter/material.dart';

void main(List<String> args) {
  runApp(MaterialApp(home: MyApp()));
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  static const int _stringLength = 14;
  final GlobalKey _key = GlobalKey();
  Size _sizeRenderBox;
  Size _sizeTextPainter;

  Size _getSizes() {
    final RenderBox renderBox = _key.currentContext.findRenderObject();
    return renderBox.size;
  }

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _sizeRenderBox = _getSizes();
      setState(() {});
    });
  }

  Size _textDetails(BuildContext context, [text = ""]) {
    final TextPainter textPainter = TextPainter(
      text: TextSpan(
        text: text,
        style: TextStyle(
            color: Colors.black,
            fontSize: Theme.of(context).textTheme.bodyText1.fontSize),
      ),
      textDirection: TextDirection.ltr,
      textScaleFactor: MediaQuery.of(context).textScaleFactor,
    )..layout(minWidth: 0, maxWidth: MediaQuery.of(context).size.width);
    return textPainter.size;
  }

  @override
  Widget build(BuildContext context) {
    _sizeTextPainter = _textDetails(context, "A" * _stringLength);

    return Scaffold(
      appBar: AppBar(title: const Text("Flutter Demo")),
      body: Center(
        child: Container(
          height: 200,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  const Text("Container - "),
                  Container(
                    height: _sizeRenderBox?.height,
                    width: _sizeRenderBox?.width,
                    child: Text("A" * _stringLength),
                    decoration: BoxDecoration(
                      border: Border.all(color: Colors.black, width: 0),
                    ),
                  ),
                ],
              ),
              Text(
                  "RenderBox - Height: ${_sizeRenderBox?.height} Width: ${_sizeRenderBox?.width}"),
              Text(
                  "TextPainter - Height: ${_sizeTextPainter?.height} Width: ${_sizeTextPainter?.width}"),
              Offstage(
                child: Container(
                  key: _key,
                  child: Text("A" * 14),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
导入“包装:颤振/材料.省道”;
void main(列表参数){
runApp(MaterialApp(home:MyApp());
}
类MyApp扩展了StatefulWidget{
@凌驾
_MyAppState createState()=>\u MyAppState();
}
类MyAppState扩展了状态{
静态常数int _stringLength=14;
最终全局键=全局键();
尺寸SizenderBox;
尺寸sizeTextPainter;
大小_getSizes(){
final RenderBox RenderBox=_key.currentContext.finderObject();
返回renderBox.size;
}
@凌驾
void initState(){
super.initState();
WidgetsBinding.instance.addPostFrameCallback((){
_sizeRenderBox=_getSizes();
setState((){});
});
}
大小_textDetails(BuildContext上下文,[text=”“]){
最终文本画家文本画家=文本画家(
text:TextSpan(
文本:文本,
样式:TextStyle(
颜色:颜色,黑色,
fontSize:Theme.of(context.textTheme.bodyText1.fontSize),
),
textDirection:textDirection.ltr,
textScaleFactor:MediaQuery.of(context).textScaleFactor,
)..布局(minWidth:0,maxWidth:MediaQuery.of(context.size.width);
返回textpainer.size;
}
@凌驾
小部件构建(构建上下文){
_sizeTextPainter=\u textDetails(上下文,“A”*\u stringLength);
返回脚手架(
appBar:appBar(标题:常量文本(“颤振演示”),
正文:中(
子:容器(
身高:200,
子:列(
mainAxisAlignment:mainAxisAlignment.spaceBetween,
crossAxisAlignment:crossAxisAlignment.center,
儿童:[
划船(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
常量文本(“容器-”,
容器(
高度:_sizenderbox?。高度,
宽度:_sizeRenderBox?。宽度,
子项:文本(“A”*\U stringLength),
装饰:盒子装饰(
边框:边框。全部(颜色:Colors.black,宽度:0),
),
),
],
),
正文(
“RenderBox-高度:${U SizenderBox?高度}宽度:${U SizenderBox?宽度}”),
正文(
“TextPainter-高度:${sizeTextPainter?.Height}宽度:${sizeTextPainter?.Width}”),
台下(
子:容器(
键:_键,
子项:文本(“A”*14),
),
),
],
),
),
),
);
}
}
字符宽度(我相信)是4-5像素,因此只需获取字符串长度*4并将其设置为容器的宽度

final containerWidth = double.parse(code.length);


Container(
  width: containerWidth,
),

这似乎太过分了,只需获取字符串的长度并将其设置为容器的宽度。如果fontsize为6或60,会发生什么情况?然后,您必须遵循以下答案:您在上面一行中引用的代码不会返回文本的宽度。它仅将容器的最大宽度限制为实际设置文本时设备宽度的70%。根据上述代码,14个字符的字符串的宽度为56或70。使用默认字体时,Android设备上14“A”的长度将为128。对于颤振,使用TextPainter或RenderBox进一步计算文本宽度并不过分。颤振框架有时在整个屏幕上每秒执行60次以上。