flutter如何实现跑马灯效果

在Flutter中如何实现跑马灯效果?我想让一段文字在容器内水平循环滚动,类似于传统的跑马灯广告效果。尝试过使用动画控制器和Transform.translate,但无法实现无限循环滚动。请问有没有现成的插件或更优雅的实现方式?最好能支持控制滚动速度、暂停和反向滚动功能。

2 回复

Flutter中实现跑马灯效果可使用SingleChildScrollView配合AnimationController,或使用第三方库如marquee。通过控制文本滚动动画实现循环滚动效果。

更多关于flutter如何实现跑马灯效果的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中实现跑马灯效果可以通过以下几种方式:

1. 使用ListView.builder + 动画控制器

class MarqueeWidget extends StatefulWidget {
  final String text;
  
  MarqueeWidget({required this.text});
  
  @override
  _MarqueeWidgetState createState() => _MarqueeWidgetState();
}

class _MarqueeWidgetState extends State<MarqueeWidget> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;
  
  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: Duration(seconds: 10),
      vsync: this,
    )..repeat();
    
    _animation = Tween<double>(
      begin: 1.0,
      end: -1.0,
    ).animate(_controller);
  }
  
  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: 50,
      child: AnimatedBuilder(
        animation: _animation,
        builder: (context, child) {
          return Transform.translate(
            offset: Offset(_animation.value * MediaQuery.of(context).size.width, 0),
            child: Text(
              widget.text,
              style: TextStyle(fontSize: 16),
            ),
          );
        },
      ),
    );
  }
  
  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

2. 使用marquee包(推荐)

首先在pubspec.yaml中添加依赖:

dependencies:
  marquee: ^2.2.1

然后使用:

import 'package:marquee/marquee.dart';

Marquee(
  text: '这是一个跑马灯文本,会自动滚动显示',
  style: TextStyle(fontSize: 16, color: Colors.black),
  scrollAxis: Axis.horizontal,
  crossAxisAlignment: CrossAxisAlignment.start,
  blankSpace: 20.0,
  velocity: 50.0,
  pauseAfterRound: Duration(seconds: 1),
  startPadding: 10.0,
  accelerationDuration: Duration(seconds: 1),
  accelerationCurve: Curves.linear,
  decelerationDuration: Duration(milliseconds: 500),
  decelerationCurve: Curves.easeOut,
)

3. 使用SingleChildScrollView + 定时器

class SimpleMarquee extends StatefulWidget {
  final String text;
  
  SimpleMarquee({required this.text});
  
  @override
  _SimpleMarqueeState createState() => _SimpleMarqueeState();
}

class _SimpleMarqueeState extends State<SimpleMarquee> {
  final ScrollController _controller = ScrollController();
  Timer? _timer;
  
  @override
  void initState() {
    super.initState();
    _startMarquee();
  }
  
  void _startMarquee() {
    _timer = Timer.periodic(Duration(milliseconds: 50), (timer) {
      if (_controller.hasClients) {
        _controller.animateTo(
          _controller.offset + 1,
          duration: Duration(milliseconds: 50),
          curve: Curves.linear,
        );
      }
    });
  }
  
  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      controller: _controller,
      scrollDirection: Axis.horizontal,
      child: Text(
        widget.text,
        style: TextStyle(fontSize: 16),
      ),
    );
  }
  
  @override
  void dispose() {
    _timer?.cancel();
    _controller.dispose();
    super.dispose();
  }
}

推荐使用marquee包,因为它功能完善、性能优化好,支持多种自定义参数,使用简单。如果需求简单,也可以选择自定义实现的方式。

回到顶部