本文介紹2種跑馬燈效果的實現:連貫式,非連貫式。效果如下圖
連貫式
實現思路:寫一個無限長度的列表(ListView),通過一個定時任務(Timer)每隔一定時間滑動一定距離(ScrollController)。這裡面比較tricky的是滑動距離的設定,你不能直接設定一個和時間成正比的值。因為頁面可能存在息屏或者跳轉到其它頁面的不可見狀態,此時是不希望有滑動的,就算你給他設定了滑動,系統並不會去滑動它。所以每次輪詢都去獲取當前列表滑動的距離(scrollController.offset),在它基礎上加上一個距離作為要滾動到的位置。
class _MarqueeContinuousState extends State<MarqueeContinuous> {
ScrollController _controller;
Timer _timer;
double _offset = 0.0;
@override
void initState() {
super.initState();
_controller = ScrollController(initialScrollOffset: _offset);
_timer = Timer.periodic(widget.duration, (timer) {
double newOffset = _controller.offset + widget.stepOffset;
if (newOffset != _offset) {
_offset = newOffset;
_controller.animateTo(_offset,
duration: widget.duration, curve: Curves.linear);
}
});
}
@override
void dispose() {
_timer.cancel();
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ListView.builder(
scrollDirection: Axis.horizontal,
controller: _controller,
itemBuilder: (context, index) {
return widget.child;
});
}
}
複製程式碼
非連貫式
實現思路:通過不斷播放平移動畫來實現(FractionalTranslation)。這裡需要注意的是,動畫是全螢幕展示的,如果你要讓它只在控制元件範圍內顯示,需要把它包裹在ClipRect中(ClipRect會把超出控制元件部分裁剪掉)。另外要使超出螢幕寬度的文字不被摺疊,需要把控制元件包裹在SingleChildScrollView中。
class _MarqueeSingleState extends State<MarqueeSingle> with SingleTickerProviderStateMixin {
AnimationController _controller;
Animation<Offset> _animation;
@override
void initState() {
super.initState();
_controller =
AnimationController(vsync: this, duration: Duration(seconds: 10));
_animation = Tween<Offset>(begin: Offset(1.0, 0.0), end: Offset(-1.0, 0.0))
.animate(_controller);
_animation.addListener(() {
setState(() {});
});
_controller.repeat();
}
@override
Widget build(BuildContext context) {
return ClipRect(child: FractionalTranslation(
translation: _animation.value,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal, child: widget.child)));
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
複製程式碼
總結
以上是實現跑馬燈效果的2種思路,大家可以根據UI需求進行選擇。在此基礎上,你還可以做其它的自定義,如設定滾動的速度,滾動的方向等。 最後附上原始碼,以供參考。
本文版權屬於再惠研發團隊,歡迎轉載,轉載請保留出處。@akindone