flutterdartfuturedart-async

Flutter, how to return different widget based on future value?


I would like to base on a future bool value, to set different icons pass back to a data card inside a list, I tried .then or FutureBuilder, but still not successful.

Scaffold:

child: ListView.builder(
                    itemCount: fullList.length,
                    itemBuilder: (BuildContext context, int index) {
                      return dataCard(context, fullList, index);
                    }),

dataCard:

Row(
                children: [
                  Expanded(
                    flex: 8,
                    child: Text(dl[i].Name,
                        style:
                            TextStyle(color: Colors.blue[400], fontSize: 16)),
                  ),
                  Expanded(
                    flex: 1,
                    child: setFavouriteIcon(dl[i].ID),
                  ),
                ],
              ),

setFavouriteIcon:

Widget setFavouriteIcon(_id) {
  final marked = markedFavourites(_id).then((value) {  //markedFavourites returns Future<bool>
    if (value == true) {
      return Icon(
        size: 24,
        Icons.favorite,
        color: Colors.red,
      );
    } else {
      return Icon(
        size: 24,
        Icons.favorite_border_outlined,
        color: Colors.red,
      );
    }
  });
  return Text('');  //Without this line, Error: A non-null value must be returned
}}

Solution

  • You can include other state as well on FutureBuilder

    Widget setFavouriteIcon(_id) {
      return FutureBuilder(
        future: markedFavourites(_id),// you shouldn't call method directly here on statefulWidget case
        builder: (context, snapshot) {
          
          final value = snapshot.hasData && (snapshot.data as bool? ?? false);
          if (value == true) {
            return Icon(
              size: 24,
              Icons.favorite,
              color: Colors.red,
            );
          } else {
            return Icon(
              size: 24,
              Icons.favorite_border_outlined,
              color: Colors.red,
            );
          }
        },
      );
    }