我正在尝试在BoxFit.scaleDown
的适合属性中使用FittedBox
来缩放Text
窗口小部件中的字体以容纳不同长度的字符串。
但是,下面的代码将缩小整个字符串并使其适合一行。对于下面的示例,我希望缩小字体,以便字符串可以放在两行上(maxLines
Text
小部件的属性。
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Multi-Line Label Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Multi-Line Label Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
final textStyle = const TextStyle(fontSize: 28.0);
final text =
'Lorem Ipsum is simply dummy text of the printing and typesetting'
'industry. Lorem Ipsum has been the industry\'s standard dummy text'
'ever since the 1500s, when an unknown printer took a galley of type'
'and scrambled it to make a type specimen book.';
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new FittedBox(
fit: BoxFit.scaleDown,
child: new Text(
text,
maxLines: 2,
style: textStyle,
textAlign: TextAlign.center,
),
),
],
),
),
);
}
}
答案 0 :(得分:3)
根据您想要的限制,我们有两个现成的解决方案。
如果您喜欢布局在某些参考屏幕尺寸上的外观,想要将文本区域视为一个框,并且只是在给定其他大小的屏幕的情况下向上或向下缩放整个框,则此解决方案有效。
参考参考屏幕。把所有东西按照预期排好。找出包含文本的框的大小(例如,通过在调试期间按't'显示渲染树)。然后用包含与测量尺寸相同的SizedBox
的包装框包装。然后用FittedBox
包装它。
限制基本上是在所有屏幕上以完全相同的方式布置文本,并且文本框的宽高比也相同。
鉴于父级具有可变大小,首先使用LayoutBuilder
在运行时获取父级的大小,然后手动调整子文本小部件中的字体大小以确保其适合。
文本布局更流畅,包含框可以具有不同的宽高比,但您必须检查与您拥有的字体大小开关一样多的屏幕尺寸。虽然使用widget tests
可以很容易地确保文本不会在任何屏幕大小上溢出如果有更多涉及相关字体缩放的通用用例的具体示例,我们还可以创建更复杂但自动的方法
答案 1 :(得分:3)
您可以使用自动文本包
https://pub.dartlang.org/packages/auto_size_text
安装后,只需将所有'Text'替换为'AutoSizeText',您会发现一切都会好起来的:)
答案 2 :(得分:1)
一个简单的嵌入式解决方案是将FittedBox
与fit: BoxFit.scaleDown
一起使用:
Container(
width: 100.0,
child: FittedBox(
fit: BoxFit.scaleDown,
// Optionally apply `alignment` to position the text inside the box:
//alignment: Alignment.topRight,
child: SizedBox(
child: Text('\$1,299.99'),
)
)
答案 3 :(得分:0)
您是否尝试使用Flexible小部件
new Flexible(
child: new Text(
text,
style: textStyle,
textAlign: TextAlign.center,
),
),
答案 4 :(得分:0)
这发生在我的应用中:
我通过计算一行中显示的最大字符数来解决,并在字符串长度较大时动态减少Text FontSize。
首先,我计算了所显示的每个字符的宽度。
为此,我需要有效的容器宽度和显示的字符数。
为了获得屏幕宽度(实际上是容器宽度),我将我的文本小部件放在LayoutBuilder
中:
new LayoutBuilder(builder: (context, constraint) {
//screen width got from the LayoutBuilder
double maxWidth = constraint.biggest.width;
//I'm going to change this dinamically
double fontSize = 33.0;
//return my widget
return new Text(
_brand.name,
maxLines: 1,
style: new TextStyle(fontSize: fontSize),
);
}
为了在新行之前显示字符,我在Text中放了一个大字符串,我手动计算了一行中显示了多少个字符。我把这个值放在const(maxCharInOneLine
)中,然后我就可以计算出单个字符宽度:我将最大值除以maxCharInOneLine
:
new LayoutBuilder(builder: (context, constraint) {
//screen width got from the LayoutBuilder
double maxWidth = constraint.biggest.width;
//chars shown manually counted
const int maxCharInOneLine = 17;
//single char width
int charWidth = (maxWidth / maxCharInOneLine).toInt();
//TO RUN IN DEBUG MODE
print("Char size with this screen and Text's TextStyle: " + charWidth.toString());
...
}
我在调试模式下运行上面的代码以获取charSize
值,然后我将它放在const中,并删除了在运行时无用的代码。
现在,通过一个恒定的字符宽度和一个可变的容器宽度(从LayoutBuilder
获得),每次最多可以匹配一行的字符数。
new LayoutBuilder(builder: (context, constraint) {
const int charWidth=16;
//screen width got from the LayoutBuilder
double maxWidth = constraint.biggest.width;
//dinamically get the char number that fits in one line with this screen
int charsPerLine = (maxWidth / charWidth).toInt();
//if it doesn't fit in a line, reduce the fontSize
double fontSize = (_brand.name.length <= charsPerLine) ? 33.0 : 23.0;
return new Text(
_brand.name,
maxLines: 1,
style: new TextStyle(fontSize: fontSize),
);
}
结果:
我的解决方案不是最好的,但在我的情况下效果很好。
我想获得反馈。 :)