Crafting a Seamless User Experience: The Power of Shimmer Effects
The Importance of Loading Indicators
When an app launches, every moment counts. A smooth, glitch-free experience is crucial to keeping users engaged and coming back for more. One essential element in achieving this is the strategic use of loading indicators, such as shimmer effects. These visual cues not only alleviate frustration but also build anticipation for the content to come.
The Magic of Shimmer Effects
Shimmer effects are a type of loading indicator that mimic the actual data being rendered on the screen. Instead of a generic progress bar, shimmer effects create a more aesthetically pleasing experience, setting the tone for a seamless interaction.
Building the App
To get started, create a new Flutter project and import the necessary dependencies:
dependencies:
flutter:
sdk: flutter
http: ^0.13.3
shimmer: ^2.0.0
stacked: ^2.2.7
Create a utils folder containing an api_constants.dart file, which defines the API endpoint for fetching character data:
class ApiConstants {
static const String apiUrl = 'https://rickandmortyapi.com/api/character';
}
Defining Models
Create two model classes: CharacterResponseModel and CharacterModel. These will hold the response data and individual character details, respectively:
class CharacterResponseModel {
List results;
CharacterResponseModel({this.results});
factory CharacterResponseModel.fromJson(Map<string, dynamic=""> json) {
return CharacterResponseModel(
results: (json['results'] as List)
.map((e) => CharacterModel.fromJson(e))
.toList(),
);
}
}
class CharacterModel {
int id;
String name;
String image;
CharacterModel({this.id, this.name, this.image});
factory CharacterModel.fromJson(Map<string, dynamic=""> json) {
return CharacterModel(
id: json['id'],
name: json['name'],
image: json['image'],
);
}
}</string,></string,>
Finding Character Data
Implement the DashboardService class, responsible for fetching character data using the http package:
class DashboardService {
Future getCharactersDetails() async {
final response = await http.get(Uri.parse(ApiConstants.apiUrl));
if (response.statusCode == 200) {
return CharacterResponseModel.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to load characters');
}
}
}
Designing the UI
Create a UI folder with a home subfolder, containing home_view.dart and home_viewmodel.dart files:
// home_viewmodel.dart
class HomeViewModel with ReactiveServiceMixin {
final DashboardService _dashboardService = DashboardService();
Future getCharacters() async {
return _dashboardService.getCharactersDetails();
}
}
// home_view.dart
class HomeView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ViewModelBuilder.reactive(
viewModel: HomeViewModel(),
builder: (context, model, child) => Scaffold(
body: model.busy
?
Shimmer Effect
: ListView.builder(
itemCount: model.characters.results.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
title: Text(model.characters.results[index].name),
leading: CircleAvatar(
backgroundImage: NetworkImage(
model.characters.results[index].image,
),
),
),
);
},
),
),
);
}
}
Setting Up a Locator
Create an app folder with an app.dart file, registering the views and services used in the app:
// app.dart
void setupLocator() {
GetIt.instance.registerLazySingleton(() => DashboardService());
}
Finishing the main.dart File
In the main.dart file, add the setupLocator function, a navigator key, and the onGenerateRoute from the generated files, linking the app from start to finish:
void main() {
setupLocator();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Shimmer Effect Demo',
onGenerateRoute: AppRouter.onGenerateRoute,
navigatorKey: GetIt.instance.navigatorKey,
);
}
}
The Result
With these steps, you’ve successfully implemented a shimmer effect in your Flutter app, elevating the overall user experience. Explore the complete source code for the sample app and discover how to integrate this feature into your own projects.