Home > Software engineering >  What can I do to make my ListView stop incrementing the data every time I open it?
What can I do to make my ListView stop incrementing the data every time I open it?

Time:10-28

My first Flutter project, which is a tricycle booking system, has just begun. Using the ListView widget, I wanted to display all of the active passengers that are saved in my Firebase Database. However, when I attempted to display it and place it in a List, all functions are working fine at first click. When you click the button to view the ListView a second time, all of the saved data are replicated. The list continues after my third click and grows by three. The image below illustrates what takes place when I repeatedly click on the ListView.

These are the blocks of code that are utilized for this functionality:

CODE for Functionality

retrieveOnlinePassengersInformation(List onlineNearestPassengersList) async
  {
    dList.clear();

    DatabaseReference ref = FirebaseDatabase.instance.ref().child("passengers");
    for(int i = 0; i<onlineNearestPassengersList.length; i  )
    {
      await ref.child(onlineNearestPassengersList[i].passengerId.toString())
          .once()
          .then((dataSnapshot)
      {
        var passengerKeyInfo = dataSnapshot.snapshot.value;
        dList.add(passengerKeyInfo);
        print("passengerKey Info: "   dList.toString());
      });
    }
  }

CODE for the UI

body: ListView.builder(
        itemCount: dList.length,
        itemBuilder: (BuildContext context, int index)
        {
          return GestureDetector(
            onTap: ()
            {
             setState(() {
               chosenPassengerId = dList[index]["id"].toString();
             });
             Navigator.pop(context, "passengerChoosed");
            },
            child: Card(
              color: Colors.grey,
              elevation: 3,
              shadowColor: Colors.green,
              margin: EdgeInsets.all(8.0),
              child: ListTile(
                leading: Padding(
                  padding: const EdgeInsets.only(top: 2.0),
                  child: Icon(
                    Icons.account_circle_outlined,
                    size: 26.sp,
                    color: Color(0xFF777777),
                  ),
                ),
                title: Column(
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: [

                    Row(
                      children: [
                        Text(
                          dList[index]["first_name"]   " "   dList[index]["last_name"],
                          style: TextStyle(
                            fontFamily: "Montserrat",
                            fontSize: 18.sp,
                            fontWeight: FontWeight.bold,
                            color: Colors.black,
                          ),
                        ),
                        Icon(
                          Icons.verified_rounded,
                          color: Color(0xFF0CBC8B),
                          size: 22.sp,
                        ),
                      ],
                    ),
                  ],
                ),
              ),
            ),
          );
        },
      ),

Expected Result:

enter image description here

Actual Result AFTER CLICKING MANY TIMES:

enter image description here

CodePudding user response:

Made a demo for you how to call function once on load

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

  @override
  State<CustomWidgetName> createState() => _CustomWidgetNameState();
}

class _CustomWidgetNameState extends State<CustomWidgetName> {
  List? dList = [];

  void myDataFunction() async {
    // do your data fetch and add to dList
    final newList = [];
    setState(() {
      dList = newList;
    });
  }

  @override
  void initState() {
    super.initState();
    myDataFunction(); // Call your async function here
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold();
  }
}

CodePudding user response:

Try this solution.

  1. Update SelectNearestActiveDriversScreen() like this:
class SelectNearestActiveDriversScreen extends StatefulWidget
{

  DatabaseReference? referenceRideRequest;
  final List list;

  SelectNearestActiveDriversScreen({this.referenceRideRequest, required this.list});

  @override
  State<SelectNearestActiveDriversScreen> createState() => _SelectNearestActiveDriversScreenState();
}
  1. In homepage.dart, declare List dList = [];, then change line 378 like this:
Navigator.push(context, MaterialPageRoute(builder: (c)=> SelectNearestActiveDriversScreen(list: dList)));
  1. In SelectNearestActiveDriversScreen(), replace all dList with widget.list.

  2. Finally, if you are using variables in a specific file declare them in that file(not in another file) or pass them in the constructor of the class / file / widget /screen you are calling. If you would rather use global variables and state managers go for packages like GetX.

  • Related