Flutter Shimmer Effect Using Getx With API Integration

Posted By : Vikas Saini | 29-Jun-2022

 

 

The Flutter Shimmer effect shows pretty animation while fetching data from the server or local database in our flutter application. We also customize the shimmer effect with actual results. It's better for the user interface.

 

Four Steps of implementation -

 

1. Create Project and install package Shimmer, Get, and HTTP in Flutter Project.
2. Shimmer Effect. 
3. Basic Introduction Flutter State Management Getx
4. Create ApiService, GetxController, Data Model Class, and SampleDataListView UI Class. 


 

1. Create Project and install the package Shimmer, Getx, and HTTP in the flutter project.

 

1. Install Latest Android Studio then Open studio Go to File then New -> Create New Flutter Project. 
2. Add the Latest packages shimmer, getx, and HTTP to pubspec.yaml file. 
3. Click Pub Get or run the command on terminal pub to get to install packages.

 

shimmer: ^2.0.0
http: ^0.13.4
get: ^4.6.5

 

2. Shimmer Effect. 

 

 Shimmer.fromColors(
  baseColor: Colors.grey[300]!,
  highlightColor: Colors.grey[100]!,
  enabled: sampleDataController.isLoading.value,
  child: // your child 
  )

 

 

3. Basic Introduction Flutter State Management Getx. 

 

Getx is a very fast and lightweight framework. Getx is a micro-framework that provides are - 

1. State management - It's rebuilt or updated only for a particular widget. No need to set-state and Stateful Widget. 
2. Route management -  When we Navigate one Screen to another screen no need for context. Easy Navigation Like  - Get.to(() => ParticlularScreen()) 
3. Dependency injection - Dependency Injection injects the instance into another screen easily.

 

 

4.1  API Service

 

Getx Api Service fetches data over the internet. Http.get function request JSON data from the server. then we are stored  JSON data to list or variable. In HTTP package used async and await features. It performs all types of requests like Get, Post, Delete, Put, Patch, etc.

 

import 'package:http/http.dart' as http;
import 'package:shimmer_effect_flutter_getx/network/endpoint.dart';
import '../sampledatamodule/model/SampleData.dart';

class ApiService {
  static var client = http.Client();

  static Future<List<SampleData>> fetchSampleData() async {
    var response = await client.get(Uri.parse(sampleDataUrl));
    var jsonString = response.body;
    return sampleDataFromJson(jsonString);
  }
}

 

4.2 GetxController

 

Inside Getx Controller we are adding the business logic and defining all types of variables and methods. we can make an observable list or variable simply by adding the  ".obs" at the end.

 

import 'package:get/get_rx/get_rx.dart';
import 'package:get/get_state_manager/get_state_manager.dart';
import 'package:shimmer_effect_flutter_getx/appmodule/api_service.dart';
import '../model/SampleData.dart';

class SampleDataController extends GetxController {
  var isLoading = false.obs;
  var sampleDataList = <SampleData>[].obs;

  @override
  void onInit() {
    fetchSampleData();
    super.onInit();
  }

  void fetchSampleData() async {
    try {
      isLoading(true);
      var sampleData = await ApiService.fetchSampleData();
      if (sampleData != null) {
        sampleDataList.assignAll(sampleData);
      }
    } finally {
      isLoading(false);
    }
  }
}

 

 

4.3 Data Model Class

 

The  Data Model Class helps us to establish the structure of the data. when we get the data from the server. then we need a data class or model class. it's managing the server data to the model class. 

 

import 'dart:convert';

List<SampleData> sampleDataFromJson(String str) => List<SampleData>.from(json.decode(str).map((x) => SampleData.fromJson(x)));

String sampleDataToJson(List<SampleData> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class SampleData {
  SampleData({
    required this.albumId,
     required this.id,
    required this.title,
    required this.url,
    required this.thumbnailUrl,
  });

  int albumId;
  int id;
  String title;
  String url;
  String thumbnailUrl;

  factory SampleData.fromJson(Map<String, dynamic> json) => SampleData(
    albumId: json["albumId"] == null ? null : json["albumId"],
    id: json["id"] == null ? null : json["id"],
    title: json["title"] == null ? null : json["title"],
    url: json["url"] == null ? null : json["url"],
    thumbnailUrl: json["thumbnailUrl"] == null ? null : json["thumbnailUrl"],
  );

  Map<String, dynamic> toJson() => {
    "albumId": albumId == null ? null : albumId,
    "id": id == null ? null : id,
    "title": title == null ? null : title,
    "url": url == null ? null : url,
    "thumbnailUrl": thumbnailUrl == null ? null : thumbnailUrl,
  };
}

 

 

4.4 SampleDataListView UI Class

 

In the Ui dart class, we are showing the Shimmer effect while fetching data from API. 

 

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get/get_core/src/get_main.dart';
import 'package:shimmer/shimmer.dart';
import 'package:shimmer_effect_flutter_getx/sampledatamodule/controllers/SampleDataController.dart';

import '../../res/strings.dart';

class SampleDataListView extends StatelessWidget {
  final SampleDataController sampleDataController =
      Get.put(SampleDataController());

  SampleDataListView({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(flutterShimmerEffectWithGetx),
      ),
      body: Obx(() {
        if (sampleDataController.isLoading.value) {
          return Container(
            width: double.infinity,
            padding:
                const EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0),
            child: Column(
              mainAxisSize: MainAxisSize.max,
              children: [
                Expanded(
                    child: Shimmer.fromColors(
                  baseColor: Colors.grey[300]!,
                  highlightColor: Colors.grey[100]!,
                  enabled: sampleDataController.isLoading.value,
                  child: ListView.builder(
                    itemBuilder: (_, __) => Padding(
                      padding: const EdgeInsets.only(bottom: 8.0),
                      child: Row(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Container(
                            width: 150,
                            height: 100,
                            color: Colors.white,
                          ),
                          const Padding(
                              padding: EdgeInsets.symmetric(horizontal: 8.0)),
                          Expanded(
                              child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Container(
                                width: double.infinity,
                                height: 8.0,
                                color: Colors.white,
                              ),
                              const Padding(
                                  padding: EdgeInsets.symmetric(vertical: 2.0)),
                              Container(
                                width: double.infinity,
                                height: 8.0,
                                color: Colors.white,
                              ),
                              const Padding(
                                  padding: EdgeInsets.symmetric(vertical: 2.0)),
                            ],
                          ))
                        ],
                      ),
                    ),
                    itemCount: 10,
                  ),
                )),
              ],
            ),
          );
        } else {
          return ListView.builder(
              itemCount: sampleDataController.sampleDataList.length,
              itemBuilder: (context, index) {
                return Column(
                  children: [
                    Row(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Container(
                          width: 150,
                          height: 100,
                          margin: const EdgeInsets.fromLTRB(16, 8, 8, 8),
                          child: ClipRRect(
                            borderRadius: BorderRadius.circular(8),
                            child: Image.network(
                              sampleDataController
                                  .sampleDataList[index].thumbnailUrl,
                              width: 150,
                              height: 100,
                              fit: BoxFit.fill,
                              colorBlendMode: BlendMode.color,
                            ),
                          ),
                        ),
                        Flexible(
                            child: Container(
                          margin: const EdgeInsets.fromLTRB(8, 8, 8, 8),
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.start,
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Text(
                                sampleDataController
                                    .sampleDataList[index].title,
                                style: const TextStyle(fontSize: 18),
                                overflow: TextOverflow.ellipsis,
                                maxLines: 1,
                              ),
                              Text(
                                sampleDataController
                                    .sampleDataList[index].title,
                                style: const TextStyle(fontSize: 14),
                                overflow: TextOverflow.ellipsis,
                                maxLines: 1,
                              ),
                            ],
                          ),
                        ))
                      ],
                    ),
                    Container(
                      color: Colors.grey[200],
                      height: 2,
                    )
                  ],
                );
              });
        }
      }),
    );
  }
}

 

 

If you want to learn more about these implementation packages. Check the Reference link ->  Shimmer , Getx , http

 

Thanks For Reading.

 

 

The Complete Source Code Link ->  Source Code

 

 

About Author

Author Image
Vikas Saini

Vikas is an efficient Mobile Application Developer with extensive industry experience. He specializes in Android and Flutter Development, demonstrating his proficiency in both platforms. With a keen attention to detail and strong problem-solving skills, Vikas consistently delivers high-quality solutions. He has an impressive track record of working on successful projects, including Crystaleyes Flutter, Vlad Flutter (AR), 3rdi Android Mobile (AR/VR), Black Book Android Mobile, VELA VIDEO CONFERENCING APPLICATION (Using WebRTC), Wind App Mobile and TV (Video Conferencing App using Jitsi Meet SDK), INW FLUTTER MOBILE APP (Live Streaming Application using WebRTC), NCG ANDROID AND FIRETV APP, TUX-WALLET ANDROID MOBILE, and StreamlyTV (Android).

Request for Proposal

Name is required

Comment is required

Sending message..