Home > Blockchain >  Flutter: How can I order a Future Listview builder?
Flutter: How can I order a Future Listview builder?

Time:02-18

I want to order the list from less distance to more distance but I calculate the km inside the list and the data comes from a Future builder so Im not sure if I can order this list.

Here is the code

Widget build(BuildContext context) { final UserProvider userProvider = Provider.of(context);

return Scaffold(
    appBar: null,
    body: FutureBuilder(
      future: FirebaseFirestore.instance
          .collection('users')
          .where('uid', isNotEqualTo: userProvider.getUser.uid)
          .get(),
      builder: (context, snapshot) {
        if (!snapshot.hasData) {
          return const Center(
            child: CircularProgressIndicator(),
          );
        }
        return ListView.separated(
          itemCount: (snapshot.data! as dynamic).docs.length,
          padding: const EdgeInsets.only(top: 30),
          separatorBuilder: (BuildContext context, int index) {
            return const Divider(
              color: Colors.grey,
            );
          },
          itemBuilder: (context, index) {
            String _titleName = (snapshot.data! as dynamic).docs[index]
                    ['name']  
                ' '  
                (snapshot.data! as dynamic).docs[index]['lastName'];
            return ListTile(
              title: Text(
                _titleName,
                style: const TextStyle(
                    fontWeight: FontWeight.bold, fontSize: 18),
              ),
              subtitle: Column(children: <Widget>[
                Row(children: [
                  Text(_subtitle,
                      style: const TextStyle(fontWeight: FontWeight.bold))
                ]),
                Row(children: [
                  Text('From'  
                      (snapshot.data! as dynamic).docs[index]['location']
                          ['nameL']  
                      ' distance'),
                  Text(Haversine.distance(
                          userProvider.getUser.location.latitude,
                          userProvider.getUser.location.longitude,
                          (snapshot.data! as dynamic).docs[index]
                              ['location']['latitude'],
                          (snapshot.data! as dynamic).docs[index]
                              ['location']['longitude'])  
                      ' km')
                ])
              ]),
              onTap() {}
            );
          },
        );
      },
    ));

}

CodePudding user response:

Instead of pulling the data straight up from Firestore and putting into the FutureBuilder, why don't you move this functionality inside your provided service UserProvider, for example (or another service), that way you can encapsulate your data fetching logic and your ordering logic there, as such:

class UserProvider {

Future<User> getUserData() {

  List<User> orderedUsers = [];

  QuerySnapshot<Map<String, dynamic>> usersSnapshot = await 
    FirebaseFirestore.instance
          .collection('users')
          .where('uid', isNotEqualTo: userProvider.getUser.uid)
          .get();

   // perform your ordering logic here
   // using the Haversine.distance
   // then populate the orderedUsers collection, 
   // and return it 

   return orderedUsers;

} 

Then in your FutureBuilder, just do:

FutureBuilder(
   future: userProvider.getData(),
   builder: (context, snapshot) {
      // the rest of your rendering logic
   }
)

It is good practice to encapsulate your Firebase data fetching inside a provided service, that way you can decouple it from the UI rendering logic. Just a thought.

  • Related