custom_banner.dart 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import 'dart:async';
  2. import 'package:flutter/material.dart';
  3. class CustomBanner extends StatefulWidget {
  4. final List<String> _images;
  5. final double height;
  6. final ValueChanged<int> onTap;
  7. final Curve curve;
  8. CustomBanner(
  9. this._images, {
  10. this.height = 200,
  11. this.onTap,
  12. this.curve = Curves.linear,
  13. }) : assert(_images != null);
  14. @override
  15. _CustomBannerState createState() => _CustomBannerState();
  16. }
  17. class _CustomBannerState extends State<CustomBanner> {
  18. PageController _pageController;
  19. int _curIndex;
  20. Timer _timer;
  21. @override
  22. void initState() {
  23. super.initState();
  24. _curIndex = widget._images.length * 5;
  25. _pageController = PageController(initialPage: _curIndex);
  26. _initTimer();
  27. }
  28. @override
  29. Widget build(BuildContext context) {
  30. return Stack(
  31. alignment: Alignment.bottomCenter,
  32. children: <Widget>[
  33. _buildPageView(),
  34. _buildIndicator(),
  35. ],
  36. );
  37. }
  38. Widget _buildIndicator() {
  39. var length = widget._images.length;
  40. return Positioned(
  41. bottom: 10,
  42. child: Row(
  43. children: widget._images.map((s) {
  44. return Padding(
  45. padding: const EdgeInsets.symmetric(horizontal: 3.0),
  46. child: ClipOval(
  47. child: Container(
  48. width: 8,
  49. height: 8,
  50. color: s == widget._images[_curIndex % length]
  51. ? Colors.white
  52. : Colors.grey,
  53. ),
  54. ),
  55. );
  56. }).toList(),
  57. ),
  58. );
  59. }
  60. Widget _buildPageView() {
  61. var length = widget._images.length;
  62. return Container(
  63. height: widget.height,
  64. child: PageView.builder(
  65. controller: _pageController,
  66. onPageChanged: (index) {
  67. setState(() {
  68. _curIndex = index;
  69. if (index == 0) {
  70. _curIndex = length;
  71. _changePage();
  72. }
  73. });
  74. },
  75. itemBuilder: (context, index) {
  76. return GestureDetector(
  77. onPanDown: (details) {
  78. _cancelTimer();
  79. },
  80. onTap: () {
  81. Scaffold.of(context).showSnackBar(
  82. SnackBar(
  83. content: Text('当前 page 为 ${index % length}'),
  84. duration: Duration(milliseconds: 500),
  85. ),
  86. );
  87. },
  88. child: Image.asset(
  89. widget._images[index % length],
  90. fit: BoxFit.cover,
  91. ),
  92. );
  93. },
  94. ),
  95. );
  96. }
  97. /// 点击到图片的时候取消定时任务
  98. _cancelTimer() {
  99. if (_timer != null) {
  100. _timer.cancel();
  101. _timer = null;
  102. _initTimer();
  103. }
  104. }
  105. /// 初始化定时任务
  106. _initTimer() {
  107. if (_timer == null) {
  108. _timer = Timer.periodic(Duration(seconds: 3), (t) {
  109. _curIndex++;
  110. _pageController.animateToPage(
  111. _curIndex,
  112. duration: Duration(milliseconds: 300),
  113. curve: Curves.linear,
  114. );
  115. });
  116. }
  117. }
  118. /// 切换页面,并刷新小圆点
  119. _changePage() {
  120. Timer(Duration(milliseconds: 350), () {
  121. _pageController.jumpToPage(_curIndex);
  122. });
  123. }
  124. }