You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter实现滚动(Marquee)文本Widget的方案咨询

Flutter 实现自动左右滚动的跑马灯(Marquee)文本效果

方案一:使用支持空安全的第三方包 marquee

这个包维护活跃且完全支持空安全,可直接实现所需的滚动效果。

步骤:

  1. 在pubspec.yaml中添加依赖:
dependencies:
  marquee: ^2.2.3 # 建议使用pub.dev上的最新版本
  1. 执行flutter pub get安装依赖
  2. 代码示例:
import 'package:flutter/material.dart';
import 'package:marquee/marquee.dart';

class MarqueeText extends StatelessWidget {
  final String content;

  const MarqueeText({super.key, required this.content});

  @override
  Widget build(BuildContext context) {
    return Marquee(
      text: content,
      style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
      scrollAxis: Axis.horizontal,
      blankSpace: 25.0, // 文本滚动到末尾后预留的空白间距
      velocity: 45.0, // 滚动速度,单位:像素/秒
      pauseAfterRound: const Duration(seconds: 1), // 每轮滚动结束后暂停1秒
      startPadding: 15.0, // 初始状态下文本左侧的内边距
      accelerationDuration: const Duration(milliseconds: 800), // 加速到指定速度的时长
      decelerationDuration: const Duration(milliseconds: 500), // 减速停止的时长
    );
  }
}

// 使用示例
void main() {
  runApp(const MaterialApp(
    home: Scaffold(
      body: Center(
        child: MarqueeText(
          content: '这是一段需要自动左右滚动的长文本,模拟OBS等工具中的滚动字幕效果',
        ),
      ),
    ),
  ));
}

方案二:自定义实现(无第三方依赖)

如果不想依赖外部包,可通过AnimatedBuilder结合Transform.translate手动实现,灵活性更高。

代码示例:

import 'package:flutter/material.dart';

class CustomMarquee extends StatefulWidget {
  final String text;
  final double speed; // 滚动速度(像素/秒)
  final TextStyle? style;
  final double gap; // 重复文本之间的空白间隔

  const CustomMarquee({
    super.key,
    required this.text,
    this.speed = 35,
    this.style,
    this.gap = 20,
  });

  @override
  State<CustomMarquee> createState() => _CustomMarqueeState();
}

class _CustomMarqueeState extends State<CustomMarquee> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;
  double? _textWidth;
  double? _containerWidth;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this)..repeat();
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    // 计算文本实际宽度
    final textPainter = TextPainter(
      text: TextSpan(text: widget.text, style: widget.style),
      textDirection: TextDirection.ltr,
    )..layout(maxWidth: MediaQuery.of(context).size.width);
    _textWidth = textPainter.width;
    _containerWidth = MediaQuery.of(context).size.width;

    // 根据总滚动距离和速度计算动画时长
    final totalDistance = _textWidth! + _containerWidth! + widget.gap;
    final duration = Duration(seconds: (totalDistance / widget.speed).ceil());
    _controller.duration = duration;

    // 定义滚动动画的起始和结束偏移量
    _animation = Tween<double>(
      begin: _containerWidth!,
      end: -(_textWidth! + widget.gap),
    ).animate(CurvedAnimation(parent: _controller, curve: Curves.linear));
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return ClipRect(
      child: AnimatedBuilder(
        animation: _animation,
        builder: (context, child) {
          return Transform.translate(
            offset: Offset(_animation.value, 0),
            child: Row(
              children: [
                Text(widget.text, style: widget.style),
                SizedBox(width: widget.gap),
                // 重复文本实现无缝滚动效果
                Text(widget.text, style: widget.style),
              ],
            ),
          );
        },
      ),
    );
  }
}

// 使用示例
void main() {
  runApp(const MaterialApp(
    home: Scaffold(
      body: Center(
        child: SizedBox(
          width: 300, // 限制容器宽度触发滚动
          child: CustomMarquee(
            text: '自定义跑马灯效果,无需依赖第三方包,完全支持空安全',
            speed: 40,
            style: TextStyle(fontSize: 16, color: Colors.deepPurple),
          ),
        ),
      ),
    ),
  ));
}

内容的提问来源于stack exchange,提问作者John Harrington

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 21:54:25