【发布时间】:2019-04-18 21:58:50
【问题描述】:
我想在给定的 SizedBox 中有一个文本(不能更改)。但此文本可能会不时发生变化。 所以我编写了一个类,当它适合给定大小时,它会向我显示文本居中,但当它太大时会滚动它。但在我的代码中,只有一小部分会出现错误。
它必须根据需要动态显示。
我的代码是如何工作的:
- 我默认构建一个居中的文本。这也是我得到 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.imgur.com/FFewRtB.gif(没有足够的声誉来发布图片:c)
【问题讨论】: