title: How to make my carousel slide automatically
body: <p>I made a carousel that retrieves the link of the images on Firebase Firestore. The recuperation of the images works but when the position changes the image does not change it displays only the first image, same as when I automate it. It's been a long time that I'm stuck on it and I don't know where the problem is. Here is the error I have in the console:</p>
  <pre><code>[VERBOSE-2:ui_dart_state.cc(198)] Unhandled Exception: 'package:flutter/src/widgets/scroll_controller.dart': Failed assertion: line 107 pos 12: '_positions.isNotEmpty': ScrollController not attached to any scroll views.
  #0      _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:51:61)
  #1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:40:5)
  #2      ScrollController.position (package:flutter/src/widgets/scroll_controller.dart:107:12)
  #3      PageController.animateToPage (package:flutter/src/widgets/page_view.dart:197:41)
  #4      _CarouselWidgetState.initState.&lt;anonymous closure&gt; (package:flyzik/widgets/carousel_widget.dart:36:23)
  #5      _rootRunUnary (dart:async/zone.dart:1434:47)
  #6      _CustomZone.runUnary (dart:async/zone.dart:1335:19)
  #7      _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
  #8      _CustomZone.bindUnaryCallbackGuarded.&lt;anonymous closure&gt; (dart:async/zone.dart:1281:26)
  #9      _rootRunUnary (dart:async/zone.dart:1442:13)
  #10     _CustomZone.&lt;…&gt;
  </code></pre>
  <p>Here is all my source code of carousel:</p>
  <pre><code>class CarouselWidget extends StatefulWidget {
    const CarouselWidget({Key? key}) : super(key: key);
  
    @override
    State&lt;CarouselWidget&gt; createState() =&gt; _CarouselWidgetState();
  }
  
  class _CarouselWidgetState extends State&lt;CarouselWidget&gt; {
    int _currentIndex = 0;
    late PageController _pageController;
    late Timer _timer;
    @override
    void initState() {
      _pageController = PageController(initialPage: 0);
      _timer = Timer.periodic(const Duration(seconds: 4), (Timer timer) {
        if (_currentIndex &lt; 5 - 1) {
          _currentIndex++;
        } else {
          _currentIndex = 0;
        }
  
        _pageController.animateToPage(
          _currentIndex,
          duration: const Duration(milliseconds: 350),
          curve: Curves.easeOutCubic,
        );
      });
      super.initState();
    }
  
    @override
    void dispose() {
      _pageController.dispose();
      _timer.cancel();
      super.dispose();
    }
  
    @override
    Widget build(BuildContext context) {
      return StreamBuilder&lt;List&lt;CarouselModel&gt;&gt;(
          stream: DBServices().getCarousels,
          builder: (context, snapshot) {
            if (snapshot.hasError) {
              return Center(
                child: Text('Erreur: ' + snapshot.error.toString()),
              );
            }
            if (snapshot.connectionState == ConnectionState.waiting) {
              return Shimmer.fromColors(
                baseColor: kShimmerBaseColor,
                highlightColor: kShimmerHifhtLightColor,
                child: Container(
                  width: double.infinity,
                  height: 220,
                  decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(10),
                      color: Colors.grey),
                ),
              );
            }
            final carousels = snapshot.data;
            return AspectRatio(
                    aspectRatio: 1.81,
                    child: Stack(
                      alignment: Alignment.bottomRight,
                      children: [
                        PageView.builder(
                          itemCount: carousels!.length,
                          controller: _pageController,
                          onPageChanged: (value) {
                            setState(() {
                              _currentIndex = value;
                              print(&quot;current index: $value&quot;);
                              print(&quot;current index2: $_currentIndex&quot;);
                            });
                          },
                          itemBuilder: (context, index) =&gt; ClipRRect(
                            borderRadius: BorderRadius.all(Radius.circular(12)),
                            child: CachedNetworkImage(
                              imageUrl: carousels[index].imageUrl,
                              fit: BoxFit.cover,
                            ),
                          ),
                        ),
                        Positioned(
                          bottom: defaultPadding,
                          right: defaultPadding,
                          child: Padding(
                            padding:
                                const EdgeInsets.only(left: defaultPadding / 4),
                            child: Row(
                              children: List.generate(
                                  carousels.length,
                                  (index) =&gt; IndicatorDot(
                                      isActive: index == _currentIndex)),
                            ),
                          ),
                        ),
                      ],
                    ),
                  );
          });
    }
  }
  
  class IndicatorDot extends StatelessWidget {
    const IndicatorDot({
      Key? key,
      required this.isActive,
    }) : super(key: key);
    final bool isActive;
  
    @override
    Widget build(BuildContext context) {
      return Container(
        height: getProportionateScreenHeight(4),
        width: getProportionateScreenWidth(8),
        decoration: BoxDecoration(
          color: isActive ? kBlack : Colors.white38,
          borderRadius: BorderRadius.all(
            Radius.circular(getProportionateScreenWidth(12)),
          ),
        ),
      );
    }
  }
  </code></pre>