Learn flutter carousel by copying Flipkart’s homepage carousel

Anshuman Patel
4 min readOct 15, 2021

--

Carousel is a great thing, especially when you have to show some info in the form of image.

For this article we’ll try to achieve making same carousel as the one in Flipkart’s mobile webapp.

By default, the images on carousel slides by itself too as well as we can scroll it too.

Packages we’ll need:

We’ll use 2 packages here, one for caching the image and other is for carousel.

cached_network_image:
carousel_slider:

Before we start, let’s talk about the approach to UI.

We can see that there is a dot indicator, which indicates which image is being shown now and an image.

The image is in the background while the dot indicator is in foreground, which means we need to use Stack to achieve this functionality.

First we’ll steal some info by inspecting the source code.

1. Links of images.

final List<String> flipkartCarouselImageUrlList = [
"https://rukminim1.flixcart.com/flap/700/300/image/b0e088ff138c58be.jpg?q=90",
"https://rukminim1.flixcart.com/flap/700/300/image/aebf043a3a4f15d6.jpg?q=90",
"https://rukminim1.flixcart.com/flap/700/300/image/c16af8723f41e655.jpeg?q=90",
"https://rukminim1.flixcart.com/flap/700/300/image/a395b780f474838c.jpg?q=90",
"https://rukminim1.flixcart.com/flap/700/300/image/714233634472f340.jpeg?q=90",
"https://rukminim1.flixcart.com/flap/700/300/image/24d2d83a84eee76b.jpg?q=90",
"https://rukminim1.flixcart.com/flap/700/300/image/b92081b232f55ec0.jpeg?q=90",
"https://rukminim1.flixcart.com/flap/700/300/image/4786aae94e794340.jpg?q=90",
];

2. Aspect ratio of the images.

It’s mentioned in the URL.

aspectRatio: 700/300,

A brief about “carousel_slider”

This package exposes us to a widget CarouselSlider which takes 2 required properties, items and options.

CarouselSlider(items: items, options: options,),

We need to provide a list of widgets as items. Option is of type CarouselOptions, which is also exposed from carousel_slider package and we can control things like image transition animation, transition duration, whether or not we want the carousel to slide automatically and it duration.

We also use CarouselController, to change the page based on click on indicator.

final CarouselController _controller = CarouselController();

Designing the Skeleton

This is the widget tree that will help achieve the carousel.

The code for the same is

return Scaffold(
body: SafeArea(
child: Padding(
padding: EdgeInsets.only(top: 8),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(
width: MediaQuery.of(context).size.width,
child: AspectRatio(
aspectRatio: 700/300,
child: LayoutBuilder(builder: (BuildContext context,
BoxConstraints constraints) {
return Stack(
alignment: Alignment.center,
children: [
Positioned.fill(
child: CarouselSlider(
items: flipkartCarouselImageUrlList
.map((deal) => GestureDetector(
onTap: () {
// todo -> navigate to someplace
},
child: CachedNetworkImage(
imageUrl: deal,
fit: BoxFit.fill,
),
))
.toList(),
carouselController: _controller,
options: CarouselOptions(
autoPlay: true,
viewportFraction: 1.0,
autoPlayInterval: Duration(seconds: 3),
autoPlayAnimationDuration:
Duration(milliseconds: 777),
autoPlayCurve: Curves.fastOutSlowIn,
height: constraints.maxHeight,
onPageChanged: (index, reason) {
setState(() {
_current = index;
});
}),
),
),
Positioned(
child: _buildDotsLoader(),
bottom: constraints.maxHeight * 0.05,
),
],
);
}),
),
),
],
),
),
),
);

Explanation (From top to bottom, and why):-

  1. Scaffold: To set the basic structure of the app. Although I didn’t use any of the properties here, but its a nice to have widget.
  2. SafeArea: To render our widgets in area so as to not conflict with OS specific features.
  3. Padding: Just to have some padding from top.
  4. Column: To keep child widgets in vertical manner.
  5. SizedBox: To set a fixed width to the child widget. When using aspect ratio, we need to pass either axis’s dimension so that AspectRatio can determine and set the other dimension. We set the width as the width of the screen.
  6. AspectRatio: To determine the height according to aspect ratio and width provided.
  7. LayoutBuilder: Now that we have a fixed height and width available for us to use, we will use layout builder’s constraint property to pass that to the child widget. In this case we needed to set CarouselSlider’s height, hence layout builder.
  8. Stack: To show both the CarouselSlider and Dots indicator in separate layers. We used its alignment as center, to show the indicator in the center.
  9. Positioned.fill : We used this widget with CarouselSlider as we wanted it to take all the space available inside the stack.
  10. CarouselSlider: To show and configure carousel’s parameter.
  11. GestureDetector: To be able to navigate to next page when we click on any image.
  12. CachedNetworkImage: To show the image from the image url that we extracted from the flipkart’s website.
  13. Positioned: (With bottom property) To show the dots indicator with bottom padding.

Dots Indicator

Widget _buildDotsLoader() {
return Container(
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.grey.withOpacity(0.45),
borderRadius: BorderRadius.all(Radius.circular(20))
),
padding: EdgeInsets.only(right: 8, left: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: flipkartCarouselImageUrlList.asMap().entries.map((entry) {
return GestureDetector(
onTap: () => _controller.animateToPage(entry.key),
child: Container(
width: (_current == entry.key) ? 17.0 : 8.0,
height: 8.0,
margin: EdgeInsets.symmetric(vertical: 8.0, horizontal: 4.0),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(Radius.circular(20)),
color: _current == entry.key ? Colors.white
.withOpacity(1.0) : Colors.grey
.withOpacity(0.9)),
),
);
}).toList(),
),
);
}

We are using a variable _current to store the index of current image, that we get from CarouselOption’s onPageChanged callback. And to navigate to that page we are using CarouselController’s animateToPage method.

Also we are using _current to indicate current page from others, through indicator.

Result

We get a very similar looking carousel as on flipkart’s webapp.

We also made the dots clickable and carousel would navigate to that page.

The only thing we missed was the worm animation on the dots transition.

Complete source code

Thank You

--

--