auto_scroll_list_view.dart 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import 'dart:async';
  2. import 'package:flutter/cupertino.dart';
  3. import 'package:flutter/rendering.dart';
  4. class AutoScrollListView extends StatefulWidget {
  5. final NullableIndexedWidgetBuilder itemBuilder;
  6. final int itemCount;
  7. final Axis scrollDirection;
  8. final EdgeInsetsGeometry? padding;
  9. final bool isAutoScrolling;
  10. const AutoScrollListView({
  11. super.key,
  12. required this.itemBuilder,
  13. required this.itemCount,
  14. this.padding,
  15. this.isAutoScrolling = true,
  16. this.scrollDirection = Axis.horizontal,
  17. });
  18. @override
  19. State<AutoScrollListView> createState() => _AutoScrollListViewState();
  20. }
  21. class _AutoScrollListViewState extends State<AutoScrollListView> {
  22. final ScrollController scrollController = ScrollController();
  23. Timer? _timer;
  24. bool _isUserScrolling = true;
  25. @override
  26. void initState() {
  27. super.initState();
  28. _isUserScrolling = widget.isAutoScrolling;
  29. _startAutoScroll();
  30. }
  31. @override
  32. void dispose() {
  33. super.dispose();
  34. scrollController.dispose();
  35. _timer?.cancel();
  36. }
  37. void _startAutoScroll() {
  38. _timer = Timer.periodic(Duration(milliseconds: 50), (timer) {
  39. if (!_isUserScrolling || !scrollController.hasClients) return;
  40. final maxScrollExtent = scrollController.position.maxScrollExtent;
  41. final current = scrollController.position.pixels;
  42. double next = current + 1;
  43. if (next >= maxScrollExtent) {
  44. next = 0;
  45. }
  46. scrollController.jumpTo(next);
  47. });
  48. }
  49. void _onUserScroll() {
  50. if (!_isUserScrolling) {
  51. return;
  52. }
  53. _timer?.cancel();
  54. _timer = Timer(Duration(seconds: 1), () {
  55. setState(() {
  56. _isUserScrolling = widget.isAutoScrolling;
  57. });
  58. _startAutoScroll();
  59. });
  60. }
  61. @override
  62. Widget build(BuildContext context) {
  63. return NotificationListener<UserScrollNotification>(
  64. onNotification: (notification) {
  65. if (notification.direction != ScrollDirection.idle) {
  66. _onUserScroll(); // 用户滑动时暂停自动滚动
  67. }
  68. return false; // 不阻止子组件的事件传递
  69. },
  70. child: ListView.builder(
  71. padding: widget.padding,
  72. scrollDirection: widget.scrollDirection,
  73. itemCount: 1000000,
  74. itemBuilder: (context, index) {
  75. return widget.itemBuilder(context, index % widget.itemCount);
  76. },
  77. controller: scrollController,
  78. ),
  79. );
  80. }
  81. }