I want to create slider animation with Images and also want to allow user to use swipe gesture to move back and forth. Another requirement is Page indicator. For this purpose, I used
page_indicator: ^0.1.3
Currently I am able to slide between images using swipe gesture with page indicator and now I want to animate slides repeatedly with x amount of duration. My code is below.
final PageController controller = new PageController();
@override
Widget build(BuildContext context) {
List<Widget> list = new List<Widget>();
list.add(new SliderBox(image: 'assets/shirt.png'));
list.add(new SliderBox(image: 'assets/laptops.png'));
list.add(new SliderBox(image: 'assets/bags.png'));
PageIndicatorContainer container = new PageIndicatorContainer(
pageView: new PageView(
children: list,
controller: controller,
),
length: 3,
padding: EdgeInsets.fromLTRB(10, 40, 10, 10),
indicatorSpace: 10,
indicatorColor: Colors.grey[350],
indicatorSelectorColor: Colors.grey,
);
return Stack(children: <Widget>[
Container(color: Colors.grey[100], height: double.infinity),
Container(
color: Colors.white,
child: container,
margin: EdgeInsets.only(bottom: 50)),Text('$moveToPage')
]);
class SliderBox extends StatelessWidget {
final image;
const SliderBox({Key key, this.image}) : super(key: key);
@override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
padding: EdgeInsets.all(10),
child: Image.asset(
image,
height: 300,
fit: BoxFit.fill,
));
}
}
I've modified your widget a little in order to provide you a complete example. You can do this in multiple ways, with AnimationController by itself or even combined with a custom Animation or, you can go the fastest way for what it seems that you want to achieve: using a recursive method that waits a x duration (time stand on a single page) and then animates with some new duration to the new page. For that you can for example:
Make your List
available within the state
itself in order to retrieve its length.
Create the recursive method that will handle the animation itself.
Make sure that you call it after the first frame is rendered on the screen to prevent the PageController
of being accessed before having a PageView
rendered on the screen, which you probably don't want. For that you take advantage of the WidgetsBinding.instance.addPostFrameCallback.
class Carousel extends StatefulWidget {
_CarouselState createState() => _CarouselState();
}
class _CarouselState extends State<Carousel> with SingleTickerProviderStateMixin {
final PageController _controller = PageController();
List<Widget> _list = [
SliderBox(
child: FlutterLogo(
colors: Colors.red,
)),
SliderBox(
child: FlutterLogo(
colors: Colors.green,
)),
SliderBox(
child: FlutterLogo(
colors: Colors.blue,
))
];
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => _animateSlider());
}
void _animateSlider() {
Future.delayed(Duration(seconds: 2)).then((_) {
int nextPage = _controller.page.round() + 1;
if (nextPage == _list.length) {
nextPage = 0;
}
_controller
.animateToPage(nextPage, duration: Duration(seconds: 1), curve: Curves.linear)
.then((_) => _animateSlider());
});
}
@override
Widget build(BuildContext context) {
PageIndicatorContainer container = new PageIndicatorContainer(
pageView: new PageView(
children: _list,
controller: _controller,
),
length: _list.length,
padding: EdgeInsets.fromLTRB(10, 40, 10, 10),
indicatorSpace: 10,
indicatorColor: Colors.grey[350],
indicatorSelectorColor: Colors.grey,
);
return Stack(
children: <Widget>[
Container(color: Colors.grey[100], height: double.infinity),
Container(color: Colors.white, child: container, margin: EdgeInsets.only(bottom: 50)),
],
);
}
}
class SliderBox extends StatelessWidget {
final Widget child;
const SliderBox({Key key, this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(padding: EdgeInsets.all(10), child: child);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With