25

I've made a PageView that acts as an image carousel. How do I let it scroll automatically between its pages infinitely after some delay in Flutter?

new PageView(
    children: List<Widget> {
        new Container(
            decoration: BoxDecoration(
                image: DecorationImage(image: new AssetImage(images[0]), 
                fit: BoxFit.cover
                )
            )
        ),
        new Container(
            decoration: BoxDecoration(
                image: DecorationImage(image: new AssetImage(images[1]), 
                fit: BoxFit.cover
                )
            )
        ),
        new Container(
            decoration: BoxDecoration(
                image: DecorationImage(image: new AssetImage(images[2]), 
                fit: BoxFit.cover
                )
            )
        )
    }
)
1
  • 1
    Could you provide your code and progress? What had you tried so far? Commented Jun 26, 2019 at 20:12

3 Answers 3

47

You need to add a PageController to your PageView. Then on initState() you can start a Timer.periodic() where you just jump from page to page. Like this:

Note: You have to cancel the timer when dispose the page or other events.

int _currentPage = 0;

'''
Timer? _timer;
'''

Timer _timer;
PageController _pageController = PageController(
  initialPage: 0,
);

@override
void initState() {
  super.initState();
  _timer = Timer.periodic(Duration(seconds: 5), (Timer timer) {
    if (_currentPage < 2) {
      _currentPage++;
    } else {
      _currentPage = 0;
    }

    _pageController.animateToPage(
      _currentPage,
      duration: Duration(milliseconds: 350),
      curve: Curves.easeIn,
    );
  });
}

  @override
  void dispose() {
    super.dispose();
    _timer?.cancel();
  }

@override
Widget build(BuildContext context) {
  return PageView(
    controller: _pageController,
    children: [
      Container(
        decoration: BoxDecoration(
          image: DecorationImage(
            image: new AssetImage(images[0]), 
            fit: BoxFit.cover,
          ),
        ),
      ),
      Container(
        decoration: BoxDecoration(
          image: DecorationImage(
            image: new AssetImage(images[1]), 
            fit: BoxFit.cover,
          ),
        ),
      ),
      Container(
        decoration: BoxDecoration(
          image: DecorationImage(
            image: new AssetImage(images[2]), 
            fit: BoxFit.cover,
          ),
        ),
      ),
    ],
  );
}

By the way you need to import 'dart:async' for using Timer.

Sign up to request clarification or add additional context in comments.

2 Comments

How can we start or stop this animation when a button is pressed? Instead of starting on initState()
Use Timer _timer = Timer.periodic(Duration(seconds: 5), (Timer timer){}); And do not forget to cancel _timer in dispose method. Same on button click you can stop timer by _timer.close() and again you can start timer by calling method.
3

The most effective way for me was to implement animation controllers. AnimationController and Animation. Inside a StatefulWidget with a page controller in the page view.

import 'package:flutter/material.dart';

class ChangePageViewAuto extends StatefulWidget {
  @override
  _ChangePageViewAutoState createState() => _ChangePageViewAutoState();
}

class _ChangePageViewAutoState extends State<ChangePageViewAuto>
    with SingleTickerProviderStateMixin {

  //declare the variables
  AnimationController _animationController;
  Animation<double> _nextPage;
  int _currentPage = 0;
  PageController _pageController = PageController(initialPage: 0);


  @override
  void initState() {
    super.initState();
    //Start at the controller and set the time to switch pages
    _animationController =
        new AnimationController(vsync: this, duration: Duration(seconds: 10));
    _nextPage = Tween(begin: 0.0, end: 1.0).animate(_animationController);

    //Add listener to AnimationController for know when end the count and change to the next page
    _animationController.addListener(() {
      if (_animationController.status == AnimationStatus.completed) {
        _animationController.reset(); //Reset the controller
        final int page = 4; //Number of pages in your PageView
        if (_currentPage < page) {
          _currentPage++;
          _pageController.animateToPage(_currentPage,
              duration: Duration(milliseconds: 300), curve: Curves.easeInSine);
        } else {
          _currentPage = 0;
        }
      }
    });
  }

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

  @override
  Widget build(BuildContext context) {
    _animationController.forward(); //Start controller with widget
          print(_nextPage.value);
    return PageView.builder(
        itemCount: 4,
        scrollDirection: Axis.horizontal,
        controller: _pageController,
        onPageChanged: (value) {
          //When page change, start the controller 
          _animationController.forward();
        },
        itemBuilder: (BuildContext context, int index) {
          
          return Container();
        });
  }
}

Comments

3

the @GaboBrandX's answer is the correct one, so I added some code to reverse the animation, for example, it will animate from 0,1,2 pages and when reaching the end, it will reverse to 2,1,0.

 final PageController _pageController = PageController(initialPage: 0);
 int _currentPage = 0;

bool end = false;
@override
void initState() {
super.initState();
Timer.periodic(Duration(seconds: 2), (Timer timer) {
  if (_currentPage == 2) {
    end = true;
  } else if (_currentPage == 0) {
    end = false;
  }

  if (end == false) {
    _currentPage++;
  } else {
    _currentPage--;
  }

  _pageController.animateToPage(
    _currentPage,
    duration: Duration(milliseconds: 1000),
    curve: Curves.easeIn,
  );
});}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.