I’m having trouble understanding async no flutter

Asked

Viewed 174 times

0

    import 'package:flutter/material.dart';
    import 'package:ouvinos_caprinos/especie/class/especie.dart';
    import 'package:ouvinos_caprinos/especie/db/especie_database.dart';
    import 'package:ouvinos_caprinos/ui/caprino/caprino_page.dart';

    class HomePage extends StatefulWidget {
      HomePage({Key key}) : super(key: key);

      @override
      _HomePageState createState() => _HomePageState();
    }

    class _HomePageState extends State<HomePage> {
      EspecieHelper _especieHelper = EspecieHelper();

      List<Especie> especies = List();
      @override
      void initState() {
        _getAllEspecies();
        super.initState();
      }

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("Rebanhos Disponiveis"),
            backgroundColor: Colors.green,
            centerTitle: true,
          ),
          body: ListView.builder(
              padding: EdgeInsets.all(10.0),
              itemCount: especies.length,
              itemBuilder: (context, index) {
                return _especieDisponiveis(context, index);
              }),
        );
      }

      Widget _especieDisponiveis(BuildContext context, int index) {
        return GestureDetector(
          child: Card(
            child: Padding(
              padding: EdgeInsets.all(10.0),
              child: Row(
                children: <Widget>[
                  Container(
                    width: 80.0,
                    height: 80.0,
                    decoration: BoxDecoration(
                      shape: BoxShape.circle,
                      image: DecorationImage(
                          image: AssetImage(
                              "images/" + especies[index].descricao.toLowerCase() + ".png"),
                          fit: BoxFit.cover),
                    ),
                  ),
                  Padding(
                    padding: EdgeInsets.only(left: 10.0),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: <Widget>[
                        Text(
                          capitalize(especies[index].descricao + "s"),
                          style: TextStyle(
                              fontSize: 22.0, fontWeight: FontWeight.bold),
                        ),
                      ],
                    ),
                  )
                ],
              ),
            ),
          ),
          onTap: () {
            _goToPage(index);
          },
        );
      }

      void _goToPage(int index) {
        if (index == 0) {
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => CaprinoPage(),
            ),
          );
        } else {
          Navigator.push(
            context,
            MaterialPageRoute(
                // builder: (context) => OvinoPage(),
                ),
          );
        }
      }

      String capitalize(String string) {
        if (string == null) {
          throw ArgumentError("string: $string");
        }

        if (string.isEmpty) {
          return string;
        }

        return string[0].toUpperCase() + string.substring(1);
      }

      Future<void> _getAllEspecies() async {
        await _especieHelper.getAllEspecies().then((listaE) {
          setState(() {
            especies = listaE;
          });
        });
      }
    }

well I’m trying to make my app less static, I’m taking the information of species from my database to improve usability and for future implementations, but I’ve been encountering failed attempts because every time I start the app( for the first time) the specific database is created until then OK, but it does not load the information to the listview, I can only view them after closing the app and open again, someone can help me ?

  • At first it seems that the return of _getAllEspecies() only happens after starting status maybe using a FutureBuilder resolve.

  • I tried several ways, I used Futurebuilder to test, but I could not, only appeared after closing the app and opening dnv (in case a way to update the page), I may not have understood the concept of Futurebuilder

  • How is the method _especieHelper.getAllEspecies()?

  • Future<List> getAllEspecies() async {&#xA; Database dbEspecie = await db;&#xA; List listMap = await dbEspecie.rawQuery("SELECT * FROM $tableName");&#xA; List<Especie> listEspecie = List();&#xA; for (Map m in listMap) {&#xA; listEspecie.add(Especie.fromMap(m));&#xA; }&#xA; return listEspecie;&#xA; }

  • 1

    Right, you can apply in Futurebuilder, I’ll leave in the answer.

1 answer

1


Based on the method

Future<List> getAllEspecies() async {
  Database dbEspecie = await db; List listMap = await dbEspecie.rawQuery("SELECT * FROM $tableName");
  List<Especie> listEspecie = List(); 
  for (Map m in listMap) { 
    listEspecie.add(Especie.fromMap(m)); 
  } 
 return listEspecie; 
}

Could be used in a Futurebuilder as follows:

@override
Widget build(BuildContext) {
  return Scaffold(
   ...

   body: FutureBuilder<List<Especie>>(
      future: _especieHelper.getAllEspecies(),
      builder: (BuildContext c, AsyncSnapshot<List<Especie>> snapshot) {
         if(snapshot.hasData) {
            // mostra a lista de especies
            return Column(
              children: snapshot.data.map(especie => ListTile(title: Text('Algum dado da especie $especie')))
            );
         }else if(snapshot.hasError) {
            return Text('Houve um erro ao listar as espécies');
         }else {
           return LinearProgressIndicator();
         }
      }

   )

  );
}

See that we pass to future for the Futurebuilder who will treat this for us.

So we can validate if Future is already finished, if it is still in progress or if there was an error. As you can see in the checks.

That way you won’t have to do that listing on initState(). Leave it to Futurebuilder anyway.

The verisications

snapshot.hasData - When true means that Future has completed and there is data available

snapshot.hasError - When true means Future has made an error

If neither is true it is because Future is still running (in this case).

Taking the value

To recover the value just use the snapshot.data. This will return you the value of Future, which in this case is a List<Especie>. So you can loop and put in a Listview, Column, Row, etc.

More details on https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

  • thank you very much for the answer, in this case solved in part the problem, I still have to restart the application( exit and enter, I think and a way to update the HomePage, so that the information can without views), would have some method that updates the page automatically??

Browser other questions tagged

You are not signed in. Login or sign up in order to post.