Reading list Switch to dark mode

    Skeleton Loader In Flutter

    Updated 29 September 2023

    In this blog, we’ll explore how to Implement in skeleton loader in Flutter .

    When creating a mobile application, user on experience is paramount. Slow loading times and empty screens can frustrate users .

    To create a smoother and more engaging loading experience, developers often to skeleton loaders.

    You may also check our flutter app development services.

    Place skeleton loaders in your UI where content is loading. Typically, you’d replace these skeleton loaders with actual content once the data is available.

    Start your headless eCommerce
    now.
    Find out More

    In modern app development, providing a smooth and engaging user experience is crucial. One way to enhance user experience is by using skeleton loading screens, which give users the impression that content is loading seamlessly.

    Implementation:-

    First we need to create a new flutter project and add the following dependencies in the pubspec.yaml file.

    dependencies:
    flutter:
    sdk: flutter
    skeleton_loader: ^2.0.0+4

    Now, run the command “flutter pub get” to add the dependencies.

    Add the following package to your class.

    import ‘package:skeleton_loader/skeleton_loader.dart’;

    Create Skeleton loader :-

    First, we will create a skeleton loader view according to our own view.

               SkeletonLoader(
                          builder: Padding(
                          padding: const EdgeInsets.symmetric(
                              vertical: 18, horizontal: 18),
                          child: Row(
                            children: [
                              Container(
                                decoration: BoxDecoration(
                                  borderRadius: BorderRadius.circular(8.0),
                                  color: Colors.red,
                                ),
                                height: 160,
                                width: 150,
                              ),
                              const SizedBox(
                                width: 10,
                              ),
                              Column(
                                children: [
                                  Container(
                                    color: Colors.white,
                                  width: MediaQuery.of(context).size.width / 2,
                                    height: 20,
                                  ),
                                  const SizedBox(
                                    height: 10,
                                  ),
                                  Container(
                                    color: Colors.white,
                                  width: MediaQuery.of(context).size.width / 2,
                                    height: 20,
                                  ),
                                  const SizedBox(
                                    height: 10,
                                  ),
                                  Container(
                                    color: Colors.white,
                                   width: MediaQuery.of(context).size.width /2,
                                    height: 20,
                                  ),
                                  const SizedBox(
                                    height: 10,
                                  ),
                                  Container(
                                    color: Colors.white,
                                   width: MediaQuery.of(context).size.width /2,
                                    height: 20,
                                  ),
                                ],
                              )
                            ],
                          ),
                        ),
                        items: 5,
                        highlightColor: Colors.blue.shade200,
                        direction: SkeletonDirection.ltr)

    Complete Code:-

    import 'package:flutter/material.dart';
    import 'package:skeleton_loader/skeleton_loader.dart';
    
    class SkeletonLoaderScreen extends StatefulWidget {
      const SkeletonLoaderScreen({Key? key}) : super(key: key);
    
      @override
      State<SkeletonLoaderScreen> createState() => _SkeletonLoaderScreenState();
    }
    
    class _SkeletonLoaderScreenState extends State<SkeletonLoaderScreen> {
      List<ItemModel> data = [
        ItemModel(
            image:
                "https://demo.bagisto.com/mobikul-mp-common/storage/product/1028/zP8lCNxK6Zwn1pESnkPRZ0Oam05Rle9Fkd6mSovl.jpg",
            title: "Enchanting Fairyland Dress",
            price: "\$15.0",
            description:
                "Enchanted Fairyland Fairy Dress Up Springtime Tulle Skirt Elasticized Bodice."),
        ItemModel(
            image:
                "https://demo.bagisto.com/mobikul-mp-common/storage/category/7/fXLqiJ0Gg7cZTP0KaGFzn8gqXy052srQ0h8so3DZ.png",
            title: "T-Shirts and Tops",
            price: "\$5.0",
            description: "T shirt is something comfortable whereas top is fancy."),
        ItemModel(
            image:
                "https://demo.bagisto.com/mobikul-mp-common/storage/product/134/1SXvD5emeW9EaQ1ggopHq0Tw5h04KdWPnKHvQZI0.png",
            title: "ladies-tank-tops",
            price: "\$20.0",
            description:
                "A tank top is a knitted piece of clothing that covers the upper part of your body and has no sleeves."),
        ItemModel(
            image:
                "https://demo.bagisto.com/mobikul-mp-common/cache/original/product/875/LXb9JsVzjEj60IWst5nX7hZnGO44fTlPCisviLjh.png",
            title: "Women Casual Regular Fit Brown Solid Overcoat",
            price: "\$25.0",
            description:
                "Women Casual Regular Fit Brown Solid Overcoat Quo commodi iusto vel ipsum voluptatum et sint necessita tibus nam vel qui laboriosam minima."),
      ];
      List<ItemModel>? itemData;
      bool isLoading = true;
    
      @override
      void initState() {
        itemView();
        super.initState();
      }
    
      Future itemView() async {
        Future.delayed(const Duration(seconds: 8), () {
          itemData = data;
          setState(() {
            isLoading = false;
          });
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
            debugShowCheckedModeBanner: false,
            home: Scaffold(
              appBar: AppBar(
                title: const Text(
                  "Skeleton Loader",
                  style: TextStyle(color: Colors.white),
                ),
              ),
              body: SingleChildScrollView(
                child: isLoading
                    ? SkeletonLoader(
                        builder: Padding(
                          padding: const EdgeInsets.symmetric(
                              vertical: 18, horizontal: 18),
                          child: Row(
                            children: [
                              Container(
                                decoration: BoxDecoration(
                                  borderRadius: BorderRadius.circular(8.0),
                                  color: Colors.red,
                                ),
                                height: 160,
                                width: 150,
                              ),
                              const SizedBox(
                                width: 10,
                              ),
                              Column(
                                children: [
                                  Container(
                                    color: Colors.white,
                                  width: MediaQuery.of(context).size.width / 2,
                                    height: 20,
                                  ),
                                  const SizedBox(
                                    height: 10,
                                  ),
                                  Container(
                                    color: Colors.white,
                                  width: MediaQuery.of(context).size.width / 2,
                                    height: 20,
                                  ),
                                  const SizedBox(
                                    height: 10,
                                  ),
                                  Container(
                                    color: Colors.white,
                                  width: MediaQuery.of(context).size.width / 2,
                                    height: 20,
                                  ),
                                  const SizedBox(
                                    height: 10,
                                  ),
                                  Container(
                                    color: Colors.white,
                                  width: MediaQuery.of(context).size.width / 2,
                                    height: 20,
                                  ),
                                ],
                              )
                            ],
                          ),
                        ),
                        items: 5,
                        highlightColor: Colors.blue.shade200,
                        direction: SkeletonDirection.ltr)
                    : ListView.builder(
                        itemCount: itemData?.length,
                        shrinkWrap: true,
                        physics: const ClampingScrollPhysics(),
                        itemBuilder: (context, index) {
                          return Padding(
                            padding: const EdgeInsets.symmetric(
                                vertical: 18, horizontal: 18),
                            child: Row(
                              children: [
                                Card(
                                  clipBehavior: Clip.antiAliasWithSaveLayer,
                                  child: Image.network(
                                    itemData?[index].image ?? "",
                                    height: 150,
                                    width: 150,
                                    fit: BoxFit.fill,
                                  ),
                                ),
                                const SizedBox(
                                  width: 10,
                                ),
                                Column(
                                  children: [
                                    SizedBox(
                                  width: MediaQuery.of(context).size.width / 2,
                                      child: Text(
                                        itemData?[index].title ?? "",
                                style: Theme.of(context).textTheme.bodyMedium,
                                      ),
                                    ),
                                    const SizedBox(
                                      height: 10,
                                    ),
                                    SizedBox(
                                  width: MediaQuery.of(context).size.width / 2,
                                      child: Text(
                                        itemData?[index].price ?? "",
                               style:Theme.of(context).textTheme.bodyMedium,
                                      ),
                                    ),
                                    const SizedBox(
                                      height: 10,
                                    ),
                                    SizedBox(
                                  width: MediaQuery.of(context).size.width / 2,
                                      child: Text(
                                        itemData?[index].description ?? "",
                                        maxLines: 2,
                                        style: Theme.of(context)
                                            .textTheme
                                            .bodyMedium
                                            ?.copyWith(color: Colors.grey),
                                      ),
                                    ),
                                  ],
                                )
                              ],
                            ),
                          );
                        }),
              ),
            ));
      }
    }
    
    class ItemModel {
      String? image;
      String? title;
      String? description;
      String? price;
    
      ItemModel({this.image, this.title, this.description, this.price});
    }

    Output:-

    We can see that the skeleton loader is displayed on the screen until the data arrives and it looks quite nice and attractive.

    Conclusion:-

    Skeleton loading screens are an effective way to enhance the user experience in your Flutter app by providing feedback during content loading.

    The skeleton_loader package simplifies the implementation of skeleton loaders, allowing you to create seamless and engaging loading screens.

    Experiment with different styles and animations to match your app’s design and delight your users.

    We have done with our implementation of Skeleton Loader In Flutter.

    Check here for more interesting blogs – https://mobikul.com/blog/

    Hope this blog helped you to better understand the implementation of Skeleton Loader In Flutter.

    To explore more of my blogs, please visit the following link.

    https://webkul.com/blog/author/sakshirai-mk754/

    Thanks for reading this blog ❤️

    References:-

    https://pub.dev/packages/skeleton_loader/example

    . . .

    Leave a Comment

    Your email address will not be published. Required fields are marked*


    Be the first to comment.

    Back to Top

    Message Sent!

    If you have more details or questions, you can reply to the received confirmation email.

    Back to Home