Как дождаться будущего объекта, прежде чем приступить к флаттеру? - PullRequest
0 голосов
/ 04 декабря 2018

Я пишу код во флаттере, в котором я использую базу данных SQFlite.Я хочу вставить виджет изображения из ресурсов и получаю имя изображения из базы данных.

    @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Single Line diagram"),backgroundColor: Colors.red.shade700,),
      body: SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: Align(
          //alignment: Alignment.center,
          child: SingleChildScrollView(
            scrollDirection: Axis.vertical,
            child: Row(
              //crossAxisAlignment: CrossAxisAlignment.center,
              children: imageList(),
            ),
          ),
        )
      ),
    );
  }

Приведенный выше код вызывает функцию imageList () для отображения списка изображений.

List<Widget> imageList(){
    List<Widget> singleLineImages = new List();
    List unit;
    for (int i = 0; i <= widget.unitsList.length-1; i++){
      for (int j = 1; j <= int.parse(widget.unitsList[i].quantity); j++){
        print("${widget.unitsList[i].bulletin}, ${widget.unitsList[i].mountType}, ${widget.unitsList[i].disconnect}");
        getfileName(widget.unitsList[i].bulletin, widget.unitsList[i].mountType, widget.unitsList[i].disconnect);
        //if(fileName != null) {
          singleLineImages.add(
              Image.asset("images/SD_Files_2100/$fileName.jpg", height: 400.0, width: 200.0,));
        //}
      }
    }
    return singleLineImages;
  }

Я получаю имя файла от метода getFileName (), который использует базу данных.

getfileName(String bulletin, String mountType, String disconnect)async {
    fileNameList = await db.getSDfileName(bulletin, disconnect, mountType);
    fileName = fileNameList[0]['FileName'];
    print("filename: $fileName");
  }

Теперь, после вызова getFileName (), программа не ждет fileName и продолжает работу., который принимает filename как ноль .Имя файла получается правильно после кода Image.asset. Есть ли способ, чтобы программа ожидала, пока не получит правильное имя файла?

1 Ответ

0 голосов
/ 04 декабря 2018

Начните выборку списка в initState() и вызовите setState при получении списка, чтобы сделать это асинхронно.Ниже вы можете найти упрощенный пример этого процесса.Также обратите внимание на оператор await перед тем, как получить имя файла.Это гарантирует, что вы вернетесь к этому куску кода после того, как все выполнено.

class ListPage extends StatefulWidget {
  @override
  _ListPageState createState() => _ListPageState();
}

class _ListPageState extends State<ListPage> {
  // This should actually be a List<MyClass> instead of widgets. 
  List<Widget> _list;

  @override
  void initState() {
    super.initState();
    _fetchList();
  }

  Future _fetchList() async {
    List<Widget> singleLineImages = new List();
    List unit;
    for (int i = 0; i <= widget.unitsList.length-1; i++){
      for (int j = 1; j <= int.parse(widget.unitsList[i].quantity); j++){
        print("${widget.unitsList[i].bulletin}, ${widget.unitsList[i].mountType}, ${widget.unitsList[i].disconnect}");
        String fileName = await getfileName(widget.unitsList[i].bulletin, widget.unitsList[i].mountType, widget.unitsList[i].disconnect);
      singleLineImages.add(
          Image.asset("images/SD_Files_2100/$fileName.jpg", height: 400.0, width: 200.0,));
      }
    }

    // call setState here to set the actual list of items and rebuild the widget.
    setState(() {
      _list = singleLineImages;
    });
  }

  @override
  Widget build(BuildContext context) {
    // Build the list, or for example a CircularProcessIndicator if it is null.
  }
}

Sidenote: вы делаете много обращений к базе данных, что, вероятно, неэффективно.Попробуйте получить необходимые данные за один вызов БД.Но это другая тема.

...