
Different Methods to Show a Loader on a Screen While Data is Loading in Flutter
Jan 10
3 min read
0
1
0

Ensuring a smooth user experience during data loading is essential when building Flutter applications. Loading indicators, or loaders, inform users that the app is processing their request and prevents them from thinking the app is unresponsive. In this blog, we’ll explore different methods to display loaders in Flutter and highlight the most efficient ones for various use cases.
1. Using CircularProgressIndicator
The CircularProgressIndicator is a built-in Flutter widget commonly used to display a spinning circle loader.
Example:
import 'package:flutter/material.dart';
class LoadingScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}
}
When to Use:
Suitable for simple loading scenarios where minimal design customization is needed.
Ideal for short loading durations.
Pros:
Easy to implement.
Requires no additional dependencies.
Cons:
Limited customization compared to third-party libraries.
2. Using LinearProgressIndicator
Another built-in widget, the LinearProgressIndicator, displays a horizontal bar that progresses while data is loading.
Example:
import 'package:flutter/material.dart';
class LinearLoaderScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Loading...'),
SizedBox(height: 20),
LinearProgressIndicator(),
],
),
);
}
}
When to Use:
Best for scenarios where users need a visual indication of progress direction.
Pros:
Clean and simple.
Great for indicating loading progress in steps.
Cons:
Not suitable for complex or animated loaders.
3. Custom Animated Loaders
Creating custom animations for loaders can enhance user experience and align with app branding.
Example:
Using Flare or Lottie animations for dynamic loaders:
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
class AnimatedLoaderScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Lottie.asset('assets/loading_animation.json'),
),
);
}
}
When to Use:
When branding and design consistency are priorities.
Ideal for apps that aim to impress users with visually appealing loaders.
Pros:
Highly customizable.
Makes the app stand out visually.
Cons:
Requires additional dependencies (e.g., Lottie).
Slightly more complex to implement.
4. Using Shimmer Effect
The shimmer package creates a placeholder loading effect, giving users a sense of the content’s layout while it’s loading.
Example:
import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
class ShimmerLoaderScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Column(
children: List.generate(5, (index) => Container(
margin: EdgeInsets.symmetric(vertical: 8.0),
height: 20.0,
color: Colors.white,
)),
),
),
),
);
}
}
When to Use:
Perfect for content-heavy apps like e-commerce or news feeds.
Pros:
Provides a skeleton layout, reducing perceived wait time.
Easy to implement with the shimmer package.
Cons:
Requires the shimmer package.
Slightly more performance-intensive than basic loaders.
5. Overlay Loader with Dialogs
Using a showDialog method to display a loader as an overlay ensures the main UI remains accessible while data is loading.
Example:
import 'package:flutter/material.dart';
class OverlayLoaderScreen extends StatefulWidget {
@override
_OverlayLoaderScreenState createState() => _OverlayLoaderScreenState();
}
class _OverlayLoaderScreenState extends State<OverlayLoaderScreen> {
bool isLoading = false;
void _startLoading() async {
setState(() {
isLoading = true;
});
await Future.delayed(Duration(seconds: 2));
setState(() {
isLoading = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Overlay Loader')),
body: Stack(
children: [
Center(
child: ElevatedButton(
onPressed: _startLoading,
child: Text('Load Data'),
),
),
if (isLoading)
Container(
color: Colors.black.withOpacity(0.5),
child: Center(
child: CircularProgressIndicator(),
),
),
],
),
);
}
}
When to Use:
Ideal for scenarios where you need to block user interaction temporarily.
Pros:
Keeps users focused on the loading process.
Easy to implement.
Cons:
Overlays can feel intrusive if overused.
6. FutureBuilder or StreamBuilder
Using FutureBuilder or StreamBuilder widgets allows you to manage loading states dynamically based on asynchronous data.
Example:
import 'package:flutter/material.dart';
class FutureLoaderScreen extends StatelessWidget {
Future<String> fetchData() async {
await Future.delayed(Duration(seconds: 3));
return "Data Loaded";
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<String>(
future: fetchData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
} else {
return Center(child: Text(snapshot.data!));
}
},
),
);
}
}
When to Use:
Suitable for handling asynchronous data fetching directly within the widget tree.
Pros:
Simplifies state management for loading.
Reduces boilerplate code.
Cons:
Limited flexibility for complex loaders.
Conclusion
Choosing the right method to display a loader depends on your app’s requirements and the type of data being loaded. For simple tasks, CircularProgressIndicator or LinearProgressIndicator are quick and easy solutions. If you want to enhance user experience, consider Shimmer effects or custom animations. For asynchronous data fetching, FutureBuilder or StreamBuilder are efficient and reliable.
By selecting the appropriate loader method, you can ensure a seamless user experience and keep your users engaged, even during loading times.