我想知道如果原始文字会溢出,Flutter是否有办法显示替代文字。
示例:
我默认显示完整日期:January 1, 2019
。
但是,如果我在小屏幕上并且会溢出(January 1...
),我想改为显示不同的字符串(1/1/2019
)。
答案 0 :(得分:3)
当前Text
实现不允许这种逻辑。您需要使用自定义溢出逻辑覆盖它们的实现。
修改是微不足道的,但请记住,如果发生溢出,你实际上是在两次计算文本。
修改需要在RenderParagraph
的{{1}}内完成。
简而言之,就像这样:
performLayout
然后需要自定义performLayout()
layout();
if (overflow) {
layoutWithText(text);
}
}
才能使用新的RichText
。然后是新的RenderParagraph
课程,以使用新的Text
。
相当多的复制粘贴。但幸运的是我会为你做的:D
以下是两次渲染相同RichText
的示例。一旦没有足够的尺寸,另一个没有限制。
使用以下代码实现:
Super long text
这是完整的工作示例(new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new SizedBox(
width: 70.0,
child: new Card(
child: new MyText(
"Super long text",
maxLines: 1,
overflowBuilder: (size) {
return new TextSpan(
text: "Hello", style: new TextStyle(color: Colors.red));
},
),
),
),
new Card(
child: new MyText(
"Super long text",
maxLines: 1,
overflowBuilder: (size) {
return new TextSpan(
text: "Hello", style: new TextStyle(color: Colors.red));
},
),
),
],
);
更改和内容)
RenderParagraph
答案 1 :(得分:1)
这是一个比Remi看起来更简单(或至少更短)的解决方案。
想法是使用LayoutBuilder包装小部件,从而获得BoxConstraints,然后使用TextPainter来确定文本是否是否适合给定的BoxConstraints。
这是一个有效的示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Text Overflow Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(title: Text("DEMO")),
body: TextOverflowDemo(),
),
);
}
}
class TextOverflowDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
int maxLines = 1;
return Container(
color: Colors.white,
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 60.0),// set maxWidth to a low value to see the result
child: LayoutBuilder(builder: (context, size) {
String text = 'January 1, 2019';
var exceeded = doesTextFit(text, maxLines, size);
return Column(children: <Widget>[
Text(
exceeded ? '1/1/2019' : text,
overflow: TextOverflow.ellipsis,
maxLines: maxLines,
),
]);
}),
),
);
}
bool doesTextFit(String text, int maxLines, BoxConstraints size,
{TextStyle textStyle}) {
TextSpan span;
if (textStyle == null) {
span = TextSpan(
text: text,
);
} else {
span = TextSpan(text: text, style: textStyle);
}
TextPainter tp = TextPainter(
maxLines: maxLines,
textAlign: TextAlign.left,
textDirection: TextDirection.ltr,
text: span,
);
tp.layout(maxWidth: size.maxWidth);
return tp.didExceedMaxLines;
}
}
答案 2 :(得分:1)
我最终得到了一个由@Mantoska的答案启发的解决方案。
import 'package:flutter/widgets.dart';
class OverflowProofText extends StatelessWidget {
const OverflowProofText({@required this.text, @required this.fallback});
final Text text;
final Text fallback;
@override
Widget build(BuildContext context) {
return SizedBox(
width: double.infinity,
child: LayoutBuilder(builder: (BuildContext context, BoxConstraints size) {
final TextPainter painter = TextPainter(
maxLines: 1,
textAlign: TextAlign.left,
textDirection: TextDirection.ltr,
text: TextSpan(
style: text.style ?? DefaultTextStyle.of(context).style,
text: text.data
),
);
painter.layout(maxWidth: size.maxWidth);
return painter.didExceedMaxLines ? fallback : text;
})
);
}
}
用法:
OverflowProofText(
text: Text('January 1, 2019'),
fallback: Text('1/1/2019', overflow: TextOverflow.fade),
),
答案 3 :(得分:0)
我为仍在寻找的人们找到了一个更简单的解决方案。 我在包装上建立了解决方案:auto_size_text 2.1.0
import 'package:auto_size_text/auto_size_text.dart';
...
AutoSizeText(
"Your text that might be too long. I'm super duper long",
maxLines: 1,
overflowReplacement: Text("I'm the new (small) replacement!"),
// minFontSize: 20
),
请注意,在触发overflowReplacement之前,此程序包还将使文本变小。您可以通过指定minFontSize来设置包中允许的最小大小。