Flutter: E-Commerce Product Carousel Page UI with Animation

Flutter UI animation page e-commerce

In this blog, I am going to introduce E-Commerce Product Carousel Page UI . Along with learning the awesome Product Carousel Page UI implementation in Flutter, we will also learn how its coding workflows and structures work.


How to Create a New Future Project

First, we need to create a new Flutter project. For that, make sure that you've installed the Flutter SDK and other Flutter app development-related requirements.

If everything is properly set up, then in order to create a project we can simply run the following command in our desired local directory:

flutter create flutter-product-detail-carousel-ui

After we've set up the project, we can navigate inside the project directory and execute the following command in the terminal to run the project in either an available emulator or an actual device:

flutter run

How to create the Main Chat Screen UI

Now, we are going to start building the UI for our chat application.

First, we need to make some simple configurations to the default boilerplate code in the main.dart file. We'll remove some default code and add the simple MaterialApp pointing to the remove Container and Call HomPage page for now:

import 'package:detailpageui/pages/home/home.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Home(),
    );
  }
}


How to Build the Animation Widgets

Inside the ./lib directory of our root project folder, we need to create a folder called ./widgets. This folder will hold all the dart files for different screens.

Inside ./lib/widgets/ directory, we need to create a file called FadeAnimation.dart. Inside the FadeAnimation.dart file, we need to add the basic Stateless widget code as shown in the code snippet below:

import 'package:flutter/material.dart';
import 'package:simple_animations/simple_animations.dart';

class FadeAnimation extends StatelessWidget {
  final double delay;
  final Widget child;
  const FadeAnimation({super.key, required this.delay, required this.child});

  @override
  Widget build(BuildContext context) {

    final duration = MultiTrackTween([
        Track("opacity").add(Duration(milliseconds: 600), Tween(begin: 0.0, end: 1.0)),
        Track("translateY").add(Duration(milliseconds: 600), Tween(begin: -25.0, end: 0.0), curve: Curves.easeOut),
        
    ]);
    
    return ControlledAnimation(
      delay: Duration(milliseconds: (600 * delay).round()),
      duration: duration.duration,
      tween: duration,
      child: child,
      builderWithChild: (context, child, animation) => Opacity(
        opacity: animation["opacity"],
        child: Transform.translate(
          offset: Offset(
            0, animation["translateY"]
          ),
          child: child,
        ),
      ),
    );
  }
}

for animation to add. simple_animations  package here link

installation Command 

flutter pub add simple_animations

How to Build the Main Home Screen

Inside the ./lib directory of our root project folder, we need to create a folder called ./pages. This folder will hold all the dart files for different screens.

Inside ./lib/pages/ directory, we need to create a file called ChatPage.dart. Inside the ChatPage.dart file, we need to add the basic Stateful widget code as shown in the code snippet below:

import 'package:detailpageui/widgets/animation/fadeAnimation.dart';
import 'package:flutter/material.dart';

class Home extends StatefulWidget {
  const Home({super.key});

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {

  final List<List<String>> products = [
    [
      'assets/images/blazer-1.jpg',
      'Dev Hub Blazer One',
      '100 \$'
    ],
    [
      'assets/images/blazer-2.jpeg',
      'Dev Hub Blazer Two',
      '200 \$'
    ],
    [
      'assets/images/blazer-3.jpeg',
      'Dev Hub Blazer Three',
      '150 \$'
    ],
    [
      'assets/images/blazer-4.jpeg',
      'Dev Hub Blazer FOUR',
      '250 \$'
    ]
  ];

  int currentIndex = 0;

  void _next(){
    setState(() {
      if(currentIndex < products.length-1){
        currentIndex++;
      }else{
        currentIndex = currentIndex;
      }
    });
  }

  void _preve(){
    setState(() {
      if(currentIndex >0 ){
        currentIndex--;
      }else{
        currentIndex = 0;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: 
      Container(
        child: Column(
          children: <Widget>[
            GestureDetector(
              onHorizontalDragEnd: (DragEndDetails details) => {
                if(details.velocity.pixelsPerSecond.dx < 0){
                  _next()
                }else if(details.velocity.pixelsPerSecond.dx > 0){
                  _preve()
                }
              },
              child: FadeAnimation(delay: 0.8, child: Container(
                width: double.infinity,
                height: 650,
                decoration: BoxDecoration(
                  image: DecorationImage(
                    image: AssetImage(products[currentIndex][0]),
                    fit: BoxFit.cover
                  )
                  
                ),
                child: Container(
                  decoration: BoxDecoration(
                    gradient: LinearGradient(
                      begin: Alignment.bottomRight,
                      colors: [
                        Colors.blueGrey,
                        Colors.grey.withOpacity(.0)
                      ]
                    )
                  ),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: <Widget>[
                      Container(
                        width: 110,
                        margin: EdgeInsets.only(bottom: 60),
                        child: Row(
                          children: buildIndicator(),
                        ),
                      )
                    ],
                  ),
                ),
              ),
              ),
            ),
            Expanded(
              child: Transform.translate(
                offset: Offset(0, -50),
                child: Container(
                  width: double.infinity,
                  padding: EdgeInsets.all(30),
                  decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.only(topLeft: Radius.circular(30), topRight: Radius.circular(30))
                  ),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                     FadeAnimation(delay:1.5, child: Text(products[currentIndex][1], style: TextStyle(color: Colors.blueGrey, fontSize: 40, fontWeight: FontWeight.bold))),
                      SizedBox(height: 10),
                      Row(
                        children: [
                          FadeAnimation(delay:1.8, child: Text(products[currentIndex][2], style: TextStyle(color: Colors.yellow[700], fontWeight: FontWeight.bold, fontSize: 22),)),
                          SizedBox(width: 10),
                          FadeAnimation(delay:2.2, child:  Row(
                            children: [
                              Icon(Icons.star, size: 18, color: Colors.yellow[700]),
                              Icon(Icons.star, size: 18, color: Colors.yellow[700]),
                              Icon(Icons.star, size: 18, color: Colors.yellow[700]),
                              Icon(Icons.star, size: 18, color: Colors.yellow[700]),
                              Icon(Icons.star_half, size: 18, color: Colors.yellow[700]),
                               SizedBox(width: 10),
                              Text("4.5/80 reviews", style: TextStyle(color: Colors.blueGrey, fontSize: 14))
                            ],
                          ))
                        ],
                      ),
                      Expanded(
                        child: Align(
                          alignment: Alignment.bottomCenter,
                          child: Container(
                            height: 50,
                            decoration: BoxDecoration(
                              color: Colors.yellow[800],
                              borderRadius: BorderRadius.circular(10)
                            ),
                            child: Center(
                              child: FadeAnimation(delay:2.5, child:   Text("Add to Cart", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),)),
                            ),
                          ),
                        ),
                      )
                    ],
                  ),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }

  Widget _indicator(bool isActive){
    return Expanded(
      child: Container(
        height: 5,
        margin: EdgeInsets.only(right: 5),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(50),
          color: isActive ? Colors.blueGrey: Colors.white
        ),
      )
    );
  }

  List<Widget> buildIndicator(){
    List<Widget> indicator = [];
    for(int i =0; i< products.length; i++){
      if(currentIndex == i){
       indicator.add(_indicator(true));
      }else{
         indicator.add(_indicator(false));
      }
     
    }
    return indicator;
  }
}

OutPut:






Flutter UI animation page e-commerce
Comments

AdBlock Detected!

Our website is made possible by displaying ads to our visitors. Please supporting us by whitelisting our website.