How to manage loadState in a screen that have multiple future builder?

Viewed 51

I have multiple FutureBuilder in one screen. You can see the futures that I use in below;

import 'package:flutter/cupertino.dart';
import 'package:shelly_ess_production/screens/services/database_service/database_service.dart';

class HomeScreenProvider extends ChangeNotifier {
  DatabaseService database = DatabaseService();
  String? _dropdownValue;

  bool _isLoading = false;

  //Loading state management
  set setLoadState(bool value) {
    _isLoading = value;
    notifyListeners();
  }

  bool get isLoading => _isLoading;

  Future<List<String>> getHomesAndSelected() async {
    List<String> homes = await database.getAllHomes();
    homes.insert(0, await database.getSelectedHome());
    List<String> uniqueHomes = homes.toSet().toList();

    return uniqueHomes;
  }

  set setDropDownValueForFirst(String? value) {
    _dropdownValue = value;
  }

  set setDropDownValue(String? value) {
    _dropdownValue = value;
    notifyListeners();
  }

  String? get dropdownValue => _dropdownValue;

  Future<void> changeSelectedHome() async {
    await database.changeSelectedHome(dropdownValue!);
  }

  Future<void> numOfRooms() async {
    await database.numberOfRooms(dropdownValue!);
  }

  Future<List<Map>> deviceAndRoomInfo() async {
    return database.numberOfRooms(dropdownValue!);
  }
}

That is the screen that I use multiple future builder.

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shelly_ess_production/constants.dart';
import 'package:shelly_ess_production/helper_widgets/loading_widget.dart';
import 'package:shelly_ess_production/screens/home_screen/components/circle_room_data.dart';
import 'package:shelly_ess_production/screens/home_screen/components/device_in_room_card.dart';
import 'package:shelly_ess_production/screens/home_screen/provider/home_screen_provider.dart';
import 'package:shelly_ess_production/screens/models/device_model.dart';
import 'package:shelly_ess_production/size_config.dart';

class Body extends StatefulWidget {
  const Body({Key? key}) : super(key: key);

  @override
  State<Body> createState() => _BodyState();
}

class _BodyState extends State<Body> {
  void initState() {
    super.initState();
    WidgetsBinding.instance!.addPostFrameCallback((_) {
      _asyncMethod();
    });
  }

  Future<void> _asyncMethod() async {
    List a = await Provider.of<HomeScreenProvider>(context, listen: false)
        .getHomesAndSelected();
    Provider.of<HomeScreenProvider>(context, listen: false).setDropDownValue =
        a[0];
  }

  @override
  Widget build(BuildContext context) {
    var providerHelper =
        Provider.of<HomeScreenProvider>(context, listen: false);

    return SafeArea(
      child: Padding(
        padding:
            EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(0.07)),
        child: SingleChildScrollView(
            child: Column(
          children: [
            SizedBox(
              height: getProportionateScreenHeight(0.02),
            ),
            Consumer<HomeScreenProvider>(builder: (context, data, child) {
              return FutureBuilder<List<String>>(
                  future: data.getHomesAndSelected(),
                  builder: (context, snapshot) {
                    if (snapshot.hasData) {
                      data.setDropDownValueForFirst = snapshot.data![0];
                      return DropdownButtonHideUnderline(
                        child: DropdownButton(
                          iconEnabledColor: kPrimaryColor,
                          iconDisabledColor: kPrimaryColor,
                          style: TextStyle(
                              color: kPrimaryColor,
                              fontSize: getProportionateScreenHeight(0.05)),
                          menuMaxHeight: getProportionateScreenHeight(0.4),
                          borderRadius: BorderRadius.circular(15),
                          key: UniqueKey(),
                          value: data.dropdownValue,
                          isExpanded: true,
                          icon: const Icon(Icons.arrow_downward),
                          onChanged: (String? newValue) async {
                            data.setDropDownValue = newValue;
                            await data.changeSelectedHome();
                          },
                          items: snapshot.data!
                              .map<DropdownMenuItem<String>>((String value) {
                            return DropdownMenuItem<String>(
                              alignment: Alignment.center,
                              value: value,
                              child: Text(value),
                            );
                          }).toList(),
                        ),
                      );
                    } else {
                      return Transform.scale(
                        scale: 0.5,
                        child: const Center(
                          child: CircularProgressIndicator(),
                        ),
                      );
                    }
                  });
            }),
            SizedBox(
              height: getProportionateScreenHeight(0.02),
            ),
            SizedBox(
              height: getProportionateScreenHeight(0.14),
              child: ListView.builder(
                  shrinkWrap: true,
                  scrollDirection: Axis.horizontal,
                  itemCount: 5,
                  itemBuilder: (context, index) {
                    return CircleRoomData(
                      title: "Oda Sayısı",
                      icon: Icons.meeting_room,
                      content: "8",
                    );
                  }),
            ),
            Consumer<HomeScreenProvider>(
              builder: (context, data, snapshot) => FutureBuilder<List<Map>>(
                  future: data.deviceAndRoomInfo(),
                  builder: (context, snapshot) {
                    if (snapshot.hasData) {
                      return ListView.builder(
                          physics: const NeverScrollableScrollPhysics(),
                          itemCount: snapshot.data!.length,
                          shrinkWrap: true,
                          itemBuilder: (context, index) {
                            return Column(
                              children: [
                                Divider(
                                  thickness:
                                      getProportionateScreenHeight(0.002),
                                ),
                                Text(
                                  snapshot.data![index]["roomName"],
                                  style: TextStyle(
                                      fontWeight: FontWeight.bold,
                                      color: kSecondaryColor,
                                      fontSize:
                                          getProportionateScreenHeight(0.03)),
                                ),
                                SizedBox(
                                  height: getProportionateScreenHeight(0.01),
                                ),
                                Text(
                                  "${(snapshot.data![index]["deviceInfo"] as List).length.toString()} Cihaz",
                                  style:
                                      const TextStyle(color: kSecondaryColor),
                                ),
                                SizedBox(
                                  height: getProportionateScreenHeight(0.02),
                                ),
                                GridView.builder(
                                    shrinkWrap: true,
                                    physics:
                                        const NeverScrollableScrollPhysics(),
                                    itemCount: (snapshot.data![index]
                                            ["deviceInfo"] as List)
                                        .length,
                                    gridDelegate:
                                        const SliverGridDelegateWithFixedCrossAxisCount(
                                      crossAxisCount: 3,
                                    ),
                                    itemBuilder: (context, indexx) {
                                      print(index);
                                      return DeviceInRoom(
                                        icon: Icons.light,
                                        productName: ((snapshot.data![index]
                                                    ["deviceInfo"]
                                                as List)[indexx] as DeviceModel)
                                            .deviceName,
                                      );
                                    })
                              ],
                            );
                          });
                    } else {
                      return const Center(
                        child: CircularProgressIndicator(),
                      );
                    }
                  }),
            )
          ],
        )),
      ),
    );
  }
}

What I want to do is showing circular progress indicator while datas are loading and when all futures completed dissmissing that circular progress indicator. Basically the question is how to communicate all of the future builders ?

0 Answers
Related