INTRODUCTION 

In the ever-evolving world of mobile and web development, a visually appealing and functional landing page plays a pivotal role in capturing user attention. Flutter, Google’s UI toolkit, empowers developers to create versatile and responsive landing pages that seamlessly adapt to various platforms. This blog will guide you through the process of building a dynamic landing page using Flutter, focusing on creating an attractive Landing page for a Music Streaming app.  

 

WHY DO WE NEED TO DO 

  • First Impressions Matter: A landing page is often the first interaction users have with your application.  
  • Highlight Features: It showcases the app’s core offerings and user benefits.  
  • Drive Engagement: A well-designed landing page can convert visitors into users by clearly communicating your value proposition.  
  • Cross-Platform Compatibility: With Flutter, you can ensure your landing page looks consistent on Android, iOS, and the web.  

 

How to set up the project: 

To build our versatile landing page, we’ll leverage the following tools and technologies:  

  • Flutter SDK: For creating natively compiled applications.  
  • Dart: Flutter’s programming language.  
  • Visual Studio Code or Android Studio: Development environment.  
  • Pub.dev Packages: Such as provider for state management, google_fonts for custom typography, and flutter_svg for scalable vector graphics.  

 

HOW DO WE SOLVE THIS 

Flutter’s widget-based architecture allows for:  

  • Reusable Components: Create modular, maintainable, and reusable widgets for efficiency.  
  • Customizable UI: Tailor layouts to match brand identity using Flutter’s flexible widgets and theming options.  
  • Cross-Platform Development: Save time and effort by building a single landing page that runs on multiple platforms.

    Install Flutter SDK: Download the latest version of Flutter from the official website.  

  • Configure an Editor: Use Visual Studio Code or Android Studio with Flutter and Dart plugins installed.  
  • Set Up a Device: Use an emulator, simulator, or physical device for testing.  
  • Run the App: Verify the setup by running flutter doctor and executing the default app with flutter run.  

 

Steps to setup the environment: 

  • Step 1:  Create a screens folder inside the lib folder  
  • Step 2:  Create a file inside the screen folder and name it as ‘dashboard.dart’ or ‘landing.dart’ as per your need.   
  • Step 3: Import material.dart for different UI styles and colors.
     
  • Step 4: Write the following code and run the command ‘flutter run’.

import ‘dart:async’; 

import ‘package:doyensys_leave_management/Screens/approval-grid.dart’; 

import ‘package:doyensys_leave_management/Screens/bottom-navigation.dart’; 

import ‘package:doyensys_leave_management/Screens/bulk-leave-approval.dart’; 

import ‘package:doyensys_leave_management/Screens/holidayslist.dart’; 

import ‘package:doyensys_leave_management/Screens/leave-approval.dart’; 

import ‘package:doyensys_leave_management/Screens/leave-availabilty.dart’; 

import ‘package:doyensys_leave_management/Screens/leave-history.dart’; 

import ‘package:doyensys_leave_management/Screens/leave-request.dart’; 

import ‘package:doyensys_leave_management/Screens/pending-leave-approval.dart’; 

import ‘package:doyensys_leave_management/Screens/userprofile.dart’; 

import ‘package:flutter/material.dart’; 

void main() => runApp(MaterialApp(home: DashboardPage(userName: ,))); 

class DashboardApp extends StatelessWidget { 

   final String userName; 

 DashboardApp({required this.userName}); 

  @override 

  Widget build(BuildContext context) { 

    return MaterialApp( 

      theme: ThemeData( 

        useMaterial3: true, // Enable Material 3 for modern styling 

      ), 

      home: DashboardPage(userName: userName), 

    ); 

  }  

} 

 

class DashboardPage extends StatefulWidget { 

    final String userName; 

  DashboardPage({required this.userName}); 

  @override 

  _DashboardPageState createState() => _DashboardPageState(); 

} 

class _DashboardPageState extends State<DashboardPage> { 

  final List<Map<String, String>> quotes = [ 

    {‘quote’: “I choose a lazy person to do a hard job.Coz,a lazy person will find an easy way to do it.”, ‘author’: ‘Bill Gates’}, 

    {‘quote’: “Monday is proof that we survived the weekend, but barely.”, ‘author’: ‘Anonymous’}, 

    {‘quote’: “Doing nothing is very hard to do. You never know when you’re finished.”, ‘author’: ‘Leslie Nielsen’}, 

    {‘quote’: “I love deadlines. I love the whooshing noise they make as they go by.”, ‘author’: ‘Douglas Adams’}, 

    {‘quote’: “I always arrive late at the office, but I make up for it by leaving early.”, ‘author’: ‘Charles Lamb’}, 

    {‘quote’: “Music can change the world because it can change people.”, ‘author’: ‘Bono’}, 

  ]; 

  int currentQuoteIndex = 0; 

  int _selectedIndex = 0; 

  late Timer _timer; 

  late PageController _pageController; 

  @override 

  void initState() { 

    super.initState(); 

    _pageController = PageController(); 

    _timer = Timer.periodic(Duration(seconds: 4), (timer) { 

      setState(() { 

        currentQuoteIndex = (currentQuoteIndex + 1) % quotes.length; 

        _pageController.animateToPage(currentQuoteIndex, 

            duration: Duration(milliseconds: 300), curve: Curves.easeInOut); 

      }); 

    }); 

  } 

  @override 

  void dispose() { 

    _timer.cancel(); 

    _pageController.dispose(); 

    super.dispose(); 

  } 

  void _onBottomNavTap(int index) { 

    setState(() { 

      _selectedIndex = index; 

    }); 

    // Navigate to the corresponding screen based on the tapped index 

    switch (index) { 

        case 1: 

        Navigator.push( 

          context, 

          MaterialPageRoute(builder: (context) => LeaveHistoryPage()), 

        ); 

        break; 

      case 2: 

        Navigator.push( 

          context, 

          MaterialPageRoute(builder: (context) => LeaveRequestScreen()), 

        ); 

        break; 

      case 3: 

        Navigator.push( 

          context, 

          MaterialPageRoute(builder: (context) => UserProfileScreen()), 

        ); 

        break; 

    } 

  }  

  @override 

  Widget build(BuildContext context) { 

    final screenWidth = MediaQuery.of(context).size.width; 

    final screenHeight = MediaQuery.of(context).size.height; 

    final isPortrait = MediaQuery.of(context).orientation == Orientation.portrait; 

    return Scaffold( 

      appBar: AppBar( 

        title: const Text(‘Home’, style: TextStyle( 

            fontSize: 18, // Reduce the size here 

            fontWeight: FontWeight.w700,     

          ),), 

        backgroundColor: Colors.deepPurple.shade300, 

        foregroundColor: Colors.white, 

         elevation: 0, 

      ), 

      body: Padding( 

        padding: EdgeInsets.all(screenWidth * 0.04), // Responsive padding 

        child: Column( 

          children: <Widget>[ 

            // Welcome message 

            Padding( 

              padding: EdgeInsets.only(bottom: screenHeight * 0.002), 

              child: Row( 

          mainAxisAlignment: MainAxisAlignment.center, 

          children: [ 

            Text( 

              ${getGreeting()}, ${widget.userName}!’, 

              style: TextStyle(fontSize: screenWidth*0.05, fontWeight:FontWeight.bold ), 

            ), 

            SizedBox(width: 4), // Adds space between text and icon 

            Icon( 

              Icons.sentiment_satisfied_alt, 

              color: Colors.deepPurple.shade300, // Set the color of the icon 

              size: 26, // Set the size of the icon 

            ), 

          ], 

        ), 

            ), 

            // Quote sec 

            Padding( 

              padding: EdgeInsets.symmetric(vertical: screenHeight * 0.002), 

              child: Column( 

                children: [ 

                  Text( 

                    ‘”${quotes[currentQuoteIndex][‘quote’]}“‘, 

                    style: TextStyle( 

                      fontSize: screenWidth * 0.040, 

                      fontStyle: FontStyle.italic, 

                      fontWeight: FontWeight.w600, 

                      color: Colors.blueGrey, 

                    ), 

                    textAlign: TextAlign.center, 

                  ), 

                  SizedBox(height: screenHeight * 0.01), 

                  Text( 

                    ‘- ${quotes[currentQuoteIndex][‘author’]}, 

                    style: TextStyle( 

                      fontSize: screenWidth * 0.04, 

                      fontWeight: FontWeight.w500, 

                      color: Colors.blueGrey, 

                    ), 

                    textAlign: TextAlign.center, 

                  ), 

                ], 

              ), 

            ), 

            // Grid with cards 

            Expanded( 

              child: GridView.count( 

                crossAxisCount: isPortrait ? 2 : 3, // Adaptive columns 

                crossAxisSpacing: screenWidth * 0.02, //hor spacing 

                mainAxisSpacing: screenHeight * 0.01, //vertical spacing 

                childAspectRatio: isPortrait ? 1.05 : 1.05, // Adaptive aspect ratio 

                children: <Widget>[ 

                  DashboardCard( 

                    title: ‘Trending’, 

                    icon: Icons.whatshot, 

                    gradientColors: [Colors.deepPurple.shade300, Colors.deepPurple.shade600], 

                    textColor: Colors.white, 

                    onTap: () { 

                      Navigator.push( 

                          context, 

                          MaterialPageRoute( 

                              builder: (context) => LeaveRequestScreen())); 

                    }, 

                  ), 

                  DashboardCard( 

                    title: ‘Your Playlist’, 

                    icon: Icons.queue_music , 

                    gradientColors: [Colors.deepPurple.shade300, Colors.deepPurple.shade600], 

                    // gradientColors: [Colors.red.shade700, Colors.red.shade900], 

                    textColor: Colors.white, 

                    onTap: () { 

                      Navigator.push( 

                          context, 

                          MaterialPageRoute( 

                              builder: (context) => HolidayListScreen())); 

                    }, 

                  ), 

                  DashboardCard( 

                    title: ‘Premium Subscription’, 

                    icon: Icons.monetization_on, 

                    gradientColors: [Colors.deepPurple.shade300, Colors.deepPurple.shade600], 

                    // gradientColors: [Colors.red.shade700, Colors.red.shade900], 

                    textColor: Colors.white, 

                    onTap: () { 

                      Navigator.push( 

                          context, 

                          MaterialPageRoute( 

                              builder: (context) => ApprovalGridPage())); 

                    }, 

                  ), 

                  DashboardCard( 

                    title: ‘Recently Played’, 

                    icon: Icons.send_time_extension, 

                    gradientColors: [Colors.deepPurple.shade300, Colors.deepPurple.shade600], 

                    // gradientColors: [Colors.red.shade700, Colors.red.shade900], 

                    textColor: Colors.white, 

                    onTap: () { 

                      Navigator.push( 

                          context, 

                          MaterialPageRoute( 

                              builder: (context) => LeaveAvailabilityScreen())); 

                    }, 

                  ), 

                ], 

              ), 

            ), 

            SizedBox(height: screenHeight * 0.025), 

            // Carousel 

            Container( 

              height: screenHeight * 0.20, 

              child: PageView( 

                controller: _pageController, 

                children: [ 

                  QuoteCard( 

                    imageUrl: https://images.pexels.com/photos/323933/pexels-photo-323933.jpeg?auto=compress&cs=tinysrgb&w=600, 

                    quote: “The only limit to our realization of tomorrow is our doubts of today.”, 

                    author: “Franklin D. Roosevelt”, 

                  ), 

                  QuoteCard( 

                    imageUrl: https://images.pexels.com/photos/207700/pexels-photo-207700.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2, 

                    quote: “Life is what happens when you’re busy making other plans.”, 

                    author: “John Lennon”, 

                  ), 

                   QuoteCard( 

                    imageUrl: https://images.pexels.com/photos/9352/glass-time-watch-business.jpg?auto=compress&cs=tinysrgb&w=600, 

                    quote: “The best way to predict your future is to create it.”, 

                    author: “Peter Drucker”, 

                  ), 

                   QuoteCard( 

                    imageUrl: https://images.pexels.com/photos/167259/pexels-photo-167259.jpeg?auto=compress&cs=tinysrgb&w=600, 

                    quote: “The journey of a thousand miles begins with a single step.”, 

                    author: “Lao Tzu”, 

                  ), 

                   QuoteCard( 

                    imageUrl: https://static.vecteezy.com/system/resources/thumbnails/047/918/672/small/music-abstract-with-headphones-horizontal-wallpaper-photo.jpg, 

                    quote: “Where words fail, music speaks.”, 

                    author: “Hans Christian Andersen”, 

                  ), 

                ], 

              ), 

            ), 

          ], 

        ), 

      ), 

      // bottomNavigationBar: BottomNavBar(), 

      bottomNavigationBar: BottomNavigationBar( 

         type: BottomNavigationBarType.fixed, 

        backgroundColor: Colors.white, 

        selectedItemColor: const Color.fromARGB(205, 172, 83, 250), 

        unselectedItemColor: const Color.fromARGB(179, 163, 163, 163), 

        currentIndex: _selectedIndex, 

        selectedLabelStyle: TextStyle( 

          fontWeight: FontWeight.w500, 

          fontSize: 14 

        ), 

         unselectedLabelStyle: TextStyle( 

          fontWeight: FontWeight.w500, 

          fontSize: 12 

        ), 

        onTap: _onBottomNavTap, 

        items: const [ 

          BottomNavigationBarItem( 

            icon: Icon(Icons.home), 

            label: ‘Home’, 

          ), 

          BottomNavigationBarItem( 

            icon: Icon(Icons.access_time_filled), 

            label: ‘History’, 

          ), 

          BottomNavigationBarItem( 

            icon: Icon(Icons.favorite), 

            label: ‘Favorites’, 

          ), 

          BottomNavigationBarItem( 

            icon: Icon(Icons.person_pin), 

            label: ‘Profile’, 

          ), 

           

        ], 

      ), 

       

    ); 

  } 

 

  String getGreeting() { 

    final hour = DateTime.now().hour; 

    if (hour < 12) { 

      return ‘Good Morning’; 

    } else if (hour < 17) { 

      return ‘Good Afternoon’; 

    } else { 

      return ‘Good Evening’; 

    } 

  } 

} 

 

// Rest of the widgets remain unchanged 

 

 

// Custom DashboardCard widget 

class DashboardCard extends StatelessWidget { 

  final String title; 

  final IconData icon; 

  final List<Color> gradientColors; 

  final Color textColor; 

  final VoidCallback onTap; 

  final double fontSize; 

 

  DashboardCard({ 

    required this.title, 

    required this.icon, 

    required this.gradientColors, 

    required this.textColor, 

    required this.onTap, 

    this.fontSize =14  }); 

 

  @override 

  Widget build(BuildContext context) { 

    return GestureDetector( 

      onTap: onTap, 

      child: Container( 

        decoration: BoxDecoration( 

          gradient: LinearGradient( 

            colors: gradientColors, 

            begin: Alignment.topLeft, 

            end: Alignment.bottomRight, 

          ), 

          borderRadius: BorderRadius.circular(12), 

        ), 

        child: Column( 

          mainAxisAlignment: MainAxisAlignment.center, 

          children: [ 

            CircleAvatar( 

              backgroundColor: Colors.white.withOpacity(0.3), 

              radius: 34, 

              child: Icon( 

                icon, 

                color: textColor, 

                size: 32, 

              ), 

            ), 

             

            SizedBox(height: 12), 

            Text( 

              title, 

              style: TextStyle( 

                color: textColor, 

                fontSize: 16, 

                fontWeight: FontWeight.bold, 

              ), 

              textAlign: TextAlign.center, 

            ), 

          ], 

        ), 

      ), 

    ); 

  } 

} 

 

// Custom QuoteCard widget 

class QuoteCard extends StatelessWidget { 

  final String imageUrl; 

  final String quote; 

  final String author; 

 

  const QuoteCard({ 

    Key? key, 

    required this.imageUrl, 

    required this.quote, 

    required this.author, 

  }) : super(key: key); 

 

  @override 

  Widget build(BuildContext context) { 

    return Container( 

      decoration: BoxDecoration( 

        image: DecorationImage( 

          image: NetworkImage(imageUrl), 

          fit: BoxFit.cover, 

        ), 

        borderRadius: BorderRadius.circular(15.0), 

      ), 

      padding: const EdgeInsets.all(10.0), 

      child: Column( 

        mainAxisAlignment: MainAxisAlignment.center, 

        children: <Widget>[ 

          Text( 

            quote, 

            style: const TextStyle( 

              fontSize: 16, 

              fontStyle: FontStyle.italic, 

              fontWeight: FontWeight.bold, 

              color: Colors.white, 

            ), 

            textAlign: TextAlign.center, 

          ), 

          const SizedBox(height: 10), 

          Text( 

            ‘- $author, 

            style: const TextStyle( 

              fontSize: 14, 

              fontWeight: FontWeight.w500, 

              color: Colors.white, 

            ), 

            textAlign: TextAlign.center, 

          ), 

        ], 

      ), 

    ); 

  } 

} 

 

The User Interface

 

CONCLUSION 

Flutter’s flexibility and widget-based approach make it an ideal choice for building versatile landing pages. By combining modular design, reusable components, and cross-platform compatibility, you can deliver an engaging user experience. Start crafting your landing page today and unlock the potential of Flutter! 

 

 

 

 

 

  

 

 

 

 

 

  

 

 

Recent Posts

Start typing and press Enter to search