本教程的结构首先介绍最简单且最有影响力的解决方案。后面的部分涵盖了较难实施且总体影响较小的解决方案,但它们对于解决特定情况很有用。

限制文本缩放的可能范围
您可以为 materialapp 设置最小和最大缩放系数,这将确保所有文本在指定范围内缩放。更小的界限需要更少的努力来保持可读性和美观性。不过,边界的选择应取决于目标受众。例如,如果您的应用程序是为老年用户设计的,您应该考虑使用较宽松的边界来满足他们的需求。
materialapp(
...
builder: (_, child) => mediaquery(
data: mediaquery.of(context).copywith(
textscaler: mediaquery.of(context)
.textscaler
.clamp(minscalefactor: 0.8, maxscalefactor: 1.6),
),
child: child!,
),
);
不要对包含文本的元素使用固定高度
看一下这段代码:
//不要这样做
sizedbox(
height: 100,
child: card(
child: center(
child: column(
mainaxisalignment: mainaxisalignment.center,
children: [
text("title", style: textstyle(fontsize: 30), maxlines: 1),
text("subtitle", maxlines: 1),
],
),
),
),
),
可能会出现什么问题?
正如您可能已经猜到的,增加文本大小可能会导致 sizedbox 的内容占用过多空间。

更好的解决方案是根据内容高度和填充来设置项目的高度。此外,您可以使用 constrainedbox 设置最小高度。
constrainedbox(
constraints: const boxconstraints(minheight: 100),
child: const card(
child: center(
child: column(
mainaxisalignment: mainaxisalignment.center,
children: [
text("title", style: textstyle(fontsize: 30), maxlines: 1),
text("subtitle", maxlines: 1),
],
),
),
),
),
因此,在 100% 比例下,我们得到了一个相同的布局,而在 160% 比例下,我们得到了一个有效的布局。

这同样适用于 listview,如果您使用 itemextent,请考虑使用字体比例计算或提供一个 prototypeitem。
让我们继续,想象一下这样的布局:

项目 a 来自上一个示例。项目 b 有一些填充,应该也能处理增加的文本缩放。屏幕底部有足够的空间。那么,可能会出什么问题呢?

不要忘记屏幕较小的手机。此外,当语言发生变化时,文本长度也会发生变化。
确保内容可滚动
首先,我们应该消除任何溢出,以确保我们的用户可以访问所有内容。添加一个简单的 singlechildscrollview 将解决这个问题。
考虑对边距和填充使用自适应值
这可能是一个有争议的方法,但想象一下您自己是一个需要使用更大字体的用户。您希望看到大量未使用的空间还是清楚地阅读文本?
让我们使用取决于逻辑像素数的值来显示文本。您可以将 smallscreenthreshold 调整为任何对您的应用程序最合理的值。
class dimens {
static const smallscreenthreshold = 300;
static bool issmallwidth(buildcontext context) {
return mediaquery.of(context).size.width /
mediaquery.textscalerof(context).scale(1) <
smallscreenthreshold;
}
static double small(buildcontext context) => issmallwidth(context) ? 4 : 8;
static double medium(buildcontext context) => issmallwidth(context) ? 8 : 16;
static double large(buildcontext context) => issmallwidth(context) ? 16 : 32;
}
请注意,如果您想遵循人机界面指南和 material design,这些值应能被 4 整除。
基于这些 dimens 我们可以为插图创建一个类:
class insets {
static edgeinsets small(buildcontext context) =>
edgeinsets.all(dimens.small(context));
static edgeinsets medium(buildcontext context) =>
edgeinsets.all(dimens.medium(context));
static edgeinsets large(buildcontext context) =>
edgeinsets.all(dimens.large(context));
}
在代码中我们将其替换为:
//padding: const edgeinsets.all(16), padding: insets.medium(context), //sizedbox(height: 16), sizedbox(height: dimens.medium(context)),
结果,我们赢得了更多的空间来在屏幕上绘制文本:

限制标题文字大小的扩展范围
增加字体比例的主要目的是使视力下降的人能够阅读内容。但是,应用程序的某些部分(例如标题)由于字体较大,可能已经可以访问。为了解决这个问题,我们可以限制文本可以放大的程度。实现此目的的一种方法是为标题创建自定义小部件:
class titletext extends statelesswidget {
final string text;
final textstyle style;
const titletext(this.text, {required this.style, super.key});
static const double maxrealfontsize = 30;
@override
widget build(buildcontext context) {
if (mediaquery.textscalerof(context).scale(style.fontsize!) >
maxrealfontsize) {
return text(
text,
style: style.copywith(
fontsize: maxrealfontsize / mediaquery.textscalerof(context).scale(1),
),
);
}
return text(text, style: style);
}
}
通过这样做,我们可以在不失去可读性的情况下赢得更多空间。您可以将该 maxrealfontsize 更改为更适合您的应用的任何值。

指定最大行数和文本溢出
不要忘记,某些文本在正常文本比例的大屏幕上可能看起来不错,但在某些其他条件下可能会占用更多的垂直空间,但您并不总是需要显示其完整内容,例如字幕。只需将 maxlines 值添加到文本小部件即可。

使用字符串的替代版本
但并不总是能够以仍然包含有用信息的方式缩短字符串。此外,不同语言的词序也不同。英语中的第一个单词可能位于另一种语言的句子末尾。让我们考虑这个国际化 (i18n) 字符串的示例:
"tasksdone": {
"one": "you have done $completed of $n tasks",
"other": "you have done $completed of $n tasks"
},
"tasksdoneshort": {
"one": "$completed/$n tasks done",
"other": "$completed/$n tasks done"
},
最有意义的部分是显示数字的部分。在较短的版本中,我们把它放在开头,使整个字符串更短。在代码中,你可以这样使用它:
text(
dimens.issmallwidth(context)
? t.tasksdoneshort(n: 10, completed: 5)
: t.tasksdone(n: 10, completed: 5),
maxlines: 1,
)

正如您在屏幕截图中看到的,缩短的版本有助于显示所需的信息。
以上就是在flutter中正确处理文本缩放的解决方案的详细内容,更多关于flutter处理文本缩放的资料请关注代码网其它相关文章!
发表评论