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.
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
Be the first to comment.