Saltar al contenido

Flutter: enfoque correcto para obtener valor de Future

Necesitamos tu apoyo para difundir nuestras secciones con relación a las ciencias informáticas.

Solución:

Veo que tienes que construir tu widget a partir de la salida de dos futuros. Puedes usar dos FutureBuilders o tener un método auxiliar para combinarlos en una unidad de código simplificada.

Además, nunca calcule / invoque la función asíncrona desde build función. Tiene que ser inicializado antes (ya sea en el constructor o initState método), de lo contrario, el widget podría terminar repintándose para siempre.

Llegando a la solución: para simplificar el código, es mejor combinar ambas salidas futuras en una sola clase como en el siguiente ejemplo:

Datos necesarios para build método:


class DataRequiredForBuild 
  String imagesPath;
  List items;

  DataRequiredForBuild(
    this.imagesPath,
    this.items,
  );

Función para obtener todos los datos requeridos:


Future _fetchAllData() async 
  return DataRequiredForBuild(
    imagesPath: await getImagesPath(),
    items: await databaseHelperGetList(),
  );

Ahora juntando todo en Widget:

Future _dataRequiredForBuild;

@override
void initState() 
  super.initState();
  // this should not be done in build method.
  _dataRequiredForBuild = _fetchAllData();


@override
Widget build(BuildContext context) 
  return Scaffold(
    //removed
    body: FutureBuilder(
      future: _dataRequiredForBuild,
      builder: (context, snapshot) 
        return snapshot.hasData
            ? ListView.builder(
                itemCount: snapshot.data.items.length,
                itemBuilder: (_, int position) 
                  final item = snapshot.data.items[position];
                  final image = "$snapshot.data.imagesPath/$item.row[0].jpg";
                  return Card(
                      child: ListTile(
                    leading: Image.asset(image),
                    title: Text(item.row[1]),
                    subtitle: Text(item.row[2]),
                    trailing: Icon(Icons.launch),
                  ));
                )
            : Center(
                child: CircularProgressIndicator(),
              );
      ,
    ),
  );


Espero eso ayude.

Mover este fragmento de código dentro FutureBuilder debería resolver el problema.

getImagesPath().then((path)
 imagesPath = path;
 print(imagesPath); //prints correct path
);

Así que tu código final debería verse así:

@override
Widget build(BuildContext context) 

return Scaffold(
    //removed
    body: FutureBuilder(
        future: databaseHelper.getList(),
        initialData: List(),
        builder: (context, snapshot) 
          return snapshot.hasData
              ? ListView.builder(
                  itemCount: snapshot.data.length,
                  itemBuilder: (_, int position) 
                    getImagesPath().then((path)
                        imagesPath = path;
                    );

                    final item = snapshot.data[position];
                    final image = "$imagesPath/$item.row[0].jpg";
                    return Card(
                        child: ListTile(
                      leading: Image.file(File(image)),
                      title: Text(item.row[1]),
                      subtitle: Text(item.row[2]),
                      trailing: Icon(Icons.launch),
                    ));
                  )
              : Center(
                  child: CircularProgressIndicator(),
                );
        ));

¡Espero eso ayude!

Comentarios y puntuaciones

Nos puedes añadir valor a nuestro contenido participando con tu veteranía en las interpretaciones.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *