本文介紹2種跑馬燈效果的實現:連貫式,非連貫式。效果以下圖 git
實現思路:寫一個無限長度的列表(ListView),經過一個定時任務(Timer)每隔必定時間滑動必定距離(ScrollController)。這裏面比較tricky的是滑動距離的設置,你不能直接設置一個和時間成正比的值。由於頁面可能存在息屏或者跳轉到其它頁面的不可見狀態,此時是不但願有滑動的,就算你給他設置了滑動,系統並不會去滑動它。因此每次輪詢都去獲取當前列表滑動的距離(scrollController.offset),在它基礎上加上一個距離做爲要滾動到的位置。github
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中。markdown
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需求進行選擇。在此基礎上,你還能夠作其它的自定義,如設置滾動的速度,滾動的方向等。 最後附上源碼,以供參考。ide
本文版權屬於再惠研發團隊,歡迎轉載,轉載請保留出處。@akindoneoop