Flutter:截断时的替代文本
Flutter: Alternative text when truncated
在某些文本小部件中,我们显示的文本在某些设备上被截断了,我们希望在这种情况下替换文本而不是截断它。
即我们显示一个像“Kamala Devi Harris”这样的名字
当名称太长而无法显示时,我们想调用一个方法并将其转换为“Kamala D. Harris”,如果名称也太长则“K. D. Harris”...“K. Harris”或甚至“K.H.”
我们如何识别当前文本被截断了?
我不知道这是否是实现您想要做的事情的最合适方法,但我们可以这样做:
创建一个自定义 Widget
,它将获取 String
的列表,从大到小,以便它可以检查哪个值适合可用的 space。
class OverflowAwareText extends StatefulWidget {
final List<String> alternativeTexts;
OverflowAwareText({this.alternativeTexts});
@override
_OverflowAwareText createState() => _OverflowAwareText();
}
class _OverflowAwareText extends State<OverflowAwareText> {
List<String> texts;
int activeTextIndex = 0;
@override
void initState() {
super.initState();
texts = widget.alternativeTexts;
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, size) {
var textSpan = TextSpan(
text: texts[activeTextIndex],
style: TextStyle(fontSize: 42),
);
// Use a textpainter to determine if it will exceed max lines
var textPainter = TextPainter(
maxLines: 1,
textAlign: TextAlign.left,
textDirection: TextDirection.ltr,
text: textSpan,
)..layout(maxWidth: size.maxWidth);
if (textPainter.didExceedMaxLines) {
if (activeTextIndex != texts.length - 1) {
WidgetsBinding.instance.addPostFrameCallback((t) {
setState(() {
activeTextIndex += 1;
});
});
}
}
return Text.rich(
textSpan,
overflow: TextOverflow.ellipsis,
maxLines: 1,
);
});
}
}
我们的OverflowAwareText
接受一个参数alternativeTexts
,即List<String>
。您必须提供一个从大到小的字符串列表。
我们现在可以使用 OverflowAwareText
:
@override
Widget build(BuildContext context) {
print('Printing from build method');
return Scaffold(
body: Center(
child: Container(
alignment: Alignment.center,
height: 50,
color: Colors.amber,
child: OverflowAwareText(
alternativeTexts: [
'Kamala Devi Harris',
'K. D. Harris',
'K. Harris',
'K. H'
],
),
),
),
);
}
我们将 OverflowAwareText
包裹在 Container
中,以便我们可以在 space.[=31= 较少的情况下检查文本是否正在更改]
结果:
Container
中没有宽度
- 在
Container
中有width = 330
- 在
Container
中有width = 180
在Container
中有width = 100
在某些文本小部件中,我们显示的文本在某些设备上被截断了,我们希望在这种情况下替换文本而不是截断它。
即我们显示一个像“Kamala Devi Harris”这样的名字
当名称太长而无法显示时,我们想调用一个方法并将其转换为“Kamala D. Harris”,如果名称也太长则“K. D. Harris”...“K. Harris”或甚至“K.H.”
我们如何识别当前文本被截断了?
我不知道这是否是实现您想要做的事情的最合适方法,但我们可以这样做:
创建一个自定义 Widget
,它将获取 String
的列表,从大到小,以便它可以检查哪个值适合可用的 space。
class OverflowAwareText extends StatefulWidget {
final List<String> alternativeTexts;
OverflowAwareText({this.alternativeTexts});
@override
_OverflowAwareText createState() => _OverflowAwareText();
}
class _OverflowAwareText extends State<OverflowAwareText> {
List<String> texts;
int activeTextIndex = 0;
@override
void initState() {
super.initState();
texts = widget.alternativeTexts;
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, size) {
var textSpan = TextSpan(
text: texts[activeTextIndex],
style: TextStyle(fontSize: 42),
);
// Use a textpainter to determine if it will exceed max lines
var textPainter = TextPainter(
maxLines: 1,
textAlign: TextAlign.left,
textDirection: TextDirection.ltr,
text: textSpan,
)..layout(maxWidth: size.maxWidth);
if (textPainter.didExceedMaxLines) {
if (activeTextIndex != texts.length - 1) {
WidgetsBinding.instance.addPostFrameCallback((t) {
setState(() {
activeTextIndex += 1;
});
});
}
}
return Text.rich(
textSpan,
overflow: TextOverflow.ellipsis,
maxLines: 1,
);
});
}
}
我们的OverflowAwareText
接受一个参数alternativeTexts
,即List<String>
。您必须提供一个从大到小的字符串列表。
我们现在可以使用 OverflowAwareText
:
@override
Widget build(BuildContext context) {
print('Printing from build method');
return Scaffold(
body: Center(
child: Container(
alignment: Alignment.center,
height: 50,
color: Colors.amber,
child: OverflowAwareText(
alternativeTexts: [
'Kamala Devi Harris',
'K. D. Harris',
'K. Harris',
'K. H'
],
),
),
),
);
}
我们将 OverflowAwareText
包裹在 Container
中,以便我们可以在 space.[=31= 较少的情况下检查文本是否正在更改]
结果:
Container
中没有宽度
- 在
Container
中有
width = 330
- 在
Container
中有
width = 180
在Container
width = 100