skip to Main Content

I am getting a list of users from firebase using StreamBuilder. I am trying to make an ‘Add as a friend’ button for the user to make friends with each other. But there is an issue I am facing. The issue here is when I click on any one of the user, all the other add buttons start with the loader. I want the loader to be only for the particular user selected.

This is before I click on anyone:
1

This is After I click on any user:
2

Here is the code I am currently using:

Column(
  children: [
    StreamBuilder<QuerySnapshot>(
        stream: FirebaseFirestore.instance
            .collection('users')
            .where("uid", isNotEqualTo: FirebaseAuth.instance.currentUser!.uid)
            .snapshots(),
        builder: (context, snapshot) {
          List<Column> clientWidgets = [];
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const CustomProgressBar();
          } else if (snapshot.hasError) {
            return Center(
              child: ErrorMessage(message: snapshot.error.toString()),
            );
          } else if (!snapshot.hasData) {
            return const Center(child: Center(child: CustomProgressBar()));
          } else {
            final clients = snapshot.data?.docs.reversed.toList();
            for (var client in clients!) {
              final clientWidget = Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  ListTile(
                    leading: FadedScaleAnimation(
                      child: CircleAvatar(
                          radius: 30.0,
                          backgroundImage: Image.network(client["avatar"] ??
                                  "https://i.pravatar.cc/300")
                              .image),
                    ),
                    trailing: GestureDetector(
                      onTap: () {
                        print(client['name']);
                        print(isLoading);
                        setState(() {
                          isLoading = true;
                        });
                        PalRequestModel palRequest = PalRequestModel(
                          name: ap.userModel.name,
                          avatar: ap.userModel.avatar,
                          phoneNumber: ap.userModel.phoneNumber,
                          uid: ap.userModel.uid,
                        );
                        ap.sendRequestToPals(
                            context: context,
                            palRequests: palRequest,
                            palId: client["uid"],
                            onSuccess: () {
                              setState(() {
                                isLoading = false;
                              });
                            });
                      },
                      child: Container(
                          padding: const EdgeInsets.all(5),
                          decoration: BoxDecoration(
                              borderRadius: BorderRadius.circular(40),
                              border: Border.all(
                                  width: 0.8, color: Colors.grey)),
                          child: isLoading
                              ? Padding(
                                  padding: const EdgeInsets.symmetric(
                                      vertical: 5.0, horizontal: 10.0),
                                  child: Row(
                                    mainAxisSize: MainAxisSize.min,
                                    mainAxisAlignment:
                                        MainAxisAlignment.center,
                                    children: [
                                      CustomProgressBar(),
                                    ],
                                  ),
                                )
                              : Row(
                                  mainAxisSize: MainAxisSize.min,
                                  children: const [
                                    Icon(
                                      Icons.person_add,
                                      size: 20,
                                    ),
                                    SizedBox(
                                      width: 5,
                                    ),
                                    Text(
                                      "add",
                                      style: TextStyle(fontSize: 18),
                                    ),
                                  ],
                                )),
                    ),
                    title: Text(
                      "${client["name"]}".toLowerCase(),
                      overflow: TextOverflow.ellipsis,
                      style: TextStyles.h2,
                    ),
                    subtitle: Text(
                      "${client["bio"]}".toLowerCase(),
                      overflow: TextOverflow.ellipsis,
                      style: TextStyles.bodyText,
                    ),
                  ),
                  
                  Divider(
                    height: 0.1,
                    thickness: 0.5,
                    endIndent: 10,
                    indent: 10,
                    color: ApplicationColors.offWhite,
                  ),
                ],
              );
              clientWidgets.add(clientWidget);
            }
          }
          return clientWidgets.isEmpty
              ? Center(
                  child: Padding(
                  padding: const EdgeInsets.only(
                      top: 10.0, bottom: 5.0, left: 10.0, right: 10.0),
                  child: Container(
                      height: 50,
                      width: MediaQuery.of(context).size.width,
                      decoration: BoxDecoration(
                          border: Border.all(
                              color: ApplicationColors.primaryColor
                                  .withOpacity(0.5),
                              width: 3),
                          borderRadius: BorderRadius.circular(10)),
                      child: Center(
                          child: Text(
                        "no pals yet",
                      ))),
                ))
              : Expanded(child: ListView(children: clientWidgets));
        }),
    
  ],
);

Please let me know what I can do about it and where I am going wrong? Thank you!

2

Answers


  1. You’re using only one global isLoading variable to control the loading animation. So when it’s true, all of your buttons will be loading at the same time.

    The best way to create the loading animation in this situation is creating a null variable for the Client like:

    dynamic isLoadingClient;
    

    The condition of loading animation:

    return isLoadingClient == client ? LoadingAnimation() : YourRealWidget();
    

    When you want to show a loading animation of a Button:

    setState(() => isLoadingClient = client);
    

    When you want to show the original Widget:

    setState(() => isLoadingClient = null);
    
    Login or Signup to reply.
  2. You are using is loading for all button, so when you change it, all button react with it, i guess it is better that u make your button widget separately in other class and put your variable in that class and send your bool through constructor.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search