marquee_widget.dart 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import 'dart:async';
  2. import 'package:flutter/cupertino.dart';
  3. // 上下滚动的消息轮播
  4. class MarqueeWidget extends StatefulWidget {
  5. /// 子视图数量
  6. final int count;
  7. ///子视图构建器
  8. final IndexedWidgetBuilder itemBuilder;
  9. ///轮播的时间间隔
  10. final int loopSeconds;
  11. const MarqueeWidget({
  12. Key? key,
  13. required this.count,
  14. required this.itemBuilder,
  15. this.loopSeconds = 3,
  16. }) : super(key: key);
  17. @override
  18. _MarqueeWidgetState createState() => _MarqueeWidgetState();
  19. }
  20. class _MarqueeWidgetState extends State<MarqueeWidget> {
  21. late PageController _controller;
  22. late Timer _timer;
  23. @override
  24. void initState() {
  25. super.initState();
  26. _controller = PageController();
  27. _timer = Timer.periodic(Duration(seconds: widget.loopSeconds), (timer) {
  28. if (_controller.page != null) {
  29. // 如果当前位于最后一页,则直接跳转到第一页,两者内容相同,跳转时视觉上无感知
  30. if (_controller.page!.round() >= widget.count) {
  31. _controller.jumpToPage(0);
  32. }
  33. _controller.nextPage(
  34. duration: const Duration(seconds: 1), curve: Curves.linear);
  35. }
  36. });
  37. }
  38. @override
  39. Widget build(BuildContext context) {
  40. return PageView.builder(
  41. scrollDirection: Axis.vertical,
  42. controller: _controller,
  43. itemBuilder: (buildContext, index) {
  44. if (index < widget.count) {
  45. return widget.itemBuilder(buildContext, index);
  46. } else {
  47. return widget.itemBuilder(buildContext, 0);
  48. }
  49. },
  50. itemCount: widget.count + 1,
  51. );
  52. }
  53. @override
  54. void dispose() {
  55. super.dispose();
  56. _controller.dispose();
  57. _timer.cancel();
  58. }
  59. }