web-dev-qa-db-ja.com

羽ばたきに進む前に、将来のオブジェクトを待つ方法は?

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 as nullが必要です。ファイル名は、Image.assetコードの後に​​正しく取得されます。 プログラムは適切なファイル名を取得するまでプログラムが待機するような方法はありますか?

4
Keshav

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.
  }
}

サイドノート:データベースに対して多くの呼び出しを行っていますが、これはおそらく非効率的です。 1回のdb呼び出しで必要なデータを取得してみてください。しかし、それは別のトピックです。

5
Jesse de Wit