我想在给定的 SsizeBox 中有一个文本(无法更改(。但是此文本可能会不时变化。所以我编写了一个类,当文本适合给定的大小时,它会向我显示居中的文本,但当它太大时,它会滚动到它上面。但是在我的代码中,只有几分之一秒会出现错误。
它必须根据需要动态显示。
我的代码如何工作:
- 默认情况下,我构建一个居中的文本。这也是我得到x像素溢出错误的地方。
- 然后,我以异步方法检查文本大小和给定大小。
- 如果文本小部件太长,我开始滚动它(AlwaysScrollingText(。
现在的问题是,如何在没有溢出 xxx 像素的情况下获得文本大小。
import 'dart:async';
import 'package:flutter/material.dart';
class ScrollingText extends StatefulWidget {
final String text;
final TextStyle style;
final Axis scrollAxis;
final double ratioOfBlankToScreen;
final double width;
ScrollingText({
@required this.text,
@required this.width,
this.style,
this.scrollAxis: Axis.horizontal,
this.ratioOfBlankToScreen: 0.25,
}) : assert(text != null, width != null);
@override
State<StatefulWidget> createState() {
return ScrollingTextState();
}
}
class ScrollingTextState extends State<ScrollingText> {
bool scroll = false;
GlobalKey _sizeKey = GlobalKey();
@override
void didUpdateWidget(ScrollingText oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.text != widget.text) scroll = false;
}
@override
Widget build(BuildContext context) {
checkScroll();
return scroll
? SizedBox(
width: widget.width,
child: AlwaysScrollingText(
text: widget.text,
style: widget.style,
))
: getText();
}
Widget getText() {
return Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(widget.text, style: widget.style, maxLines: 1, key: _sizeKey)
],
),
);
}
checkScroll() async {
await Future.delayed(Duration(milliseconds: 500));
if (_sizeKey.currentContext == null) return;
double _textWidth =
_sizeKey.currentContext.findRenderObject().paintBounds.size.width;
bool scroll = _textWidth > widget.width;
print('$_textWidth > ${widget.width}');
if (scroll != this.scroll)
setState(() {
this.scroll = scroll;
});
}
}
class AlwaysScrollingText extends StatefulWidget {
final String text;
final TextStyle style;
final double ratioOfBlankToScreen;
AlwaysScrollingText({
@required this.text,
this.style,
this.ratioOfBlankToScreen: 0.25,
}) : assert(text != null,);
@override
_AlwaysScrollingTextState createState() => _AlwaysScrollingTextState();
}
class _AlwaysScrollingTextState extends State<AlwaysScrollingText>
with SingleTickerProviderStateMixin {
ScrollController scrollController;
double screenWidth;
double screenHeight;
double position = 0.0;
Timer timer;
final double _moveDistance = 3.0;
final int _timerRest = 100;
GlobalKey _key = GlobalKey();
@override
void initState() {
super.initState();
scrollController = ScrollController();
WidgetsBinding.instance.addPostFrameCallback((callback) {
startTimer();
});
}
void startTimer() {
if (_key.currentContext != null) {
double widgetWidth = getSizeFromKey(_key).width;
timer = Timer.periodic(Duration(milliseconds: _timerRest), (timer) {
double maxScrollExtent = scrollController.position.maxScrollExtent;
double pixels = scrollController.position.pixels;
if (pixels + _moveDistance >= maxScrollExtent) {
position = (maxScrollExtent -
screenWidth * widget.ratioOfBlankToScreen +
widgetWidth) /
2 -
widgetWidth +
pixels -
maxScrollExtent;
scrollController.jumpTo(position);
}
position += _moveDistance;
scrollController.animateTo(position,
duration: Duration(milliseconds: _timerRest), curve: Curves.linear);
});
}
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
screenWidth = MediaQuery.of(context).size.width;
screenHeight = MediaQuery.of(context).size.height;
}
Widget getBothEndsChild() {
return Center(
child: Text(
widget.text,
style: widget.style,
maxLines: 1,
));
}
Widget getCenterChild() {
return Container(width: screenWidth * widget.ratioOfBlankToScreen);
}
@override
void dispose() {
super.dispose();
if (timer != null) {
timer.cancel();
}
}
@override
Widget build(BuildContext context) {
return ListView(
key: _key,
scrollDirection: Axis.horizontal,
controller: scrollController,
physics: NeverScrollableScrollPhysics(),
children: <Widget>[
getCenterChild(),
getBothEndsChild(),
],
);
}
Size getSizeFromKey(GlobalKey key) =>
key.currentContext?.findRenderObject()?.paintBounds?.size;
}
实际结果:https://i.stack.imgur.com/MnoSx.gif(没有足够的声誉来发布图像:c(
您可以将文本字段放在展开的小部件中。这是类的链接。 展开的小部件。
这是代码。 Expanded(
child: Text("hello"),
);
这个小技巧修复了这个错误:
- 将
bool scroll = _textWidth > widget.width;
替换为bool scroll = _textWidth >= widget.width;
- 删除了
getText
方法中的Row
小部件