如何正确使用FutureBuilder?

时间:2020-07-01 16:01:46

标签: flutter dart

我有一个ListView,我想在其中显示通过dbhelper从我的应用程序的SQFLite DB中读取的布尔值。 由于读写是异步的,因此我需要一点时间来了解FutureBuilder。 DB-Helper方法是:

Future<Map<String, dynamic>> getItem(String tableName, String id) async {
    Database db = await this.db;
    var result = await db.rawQuery(
        "SELECT * FROM $tableName WHERE $colId = $id ORDER BY $colCategory DESC, $colName DESC");
    Map<String, dynamic> singleMap = result[0];
    return singleMap;
  }

我的提取方法是:

 Future<bool> isObtainedDB(Settings settings) async {
    var map = await _dbHelper.getItem(_dbHelper.tblSavedata, id);
    //var map = Map<String, dynamic>();
    bool obtained = map[_dbHelper.colObtained];
    return obtained;
  }

我被困在试图将构建器包装在Checkbox周围的地方,以进行概念验证:

FutureBuilder(
          future: isObtainedDB(settings),
          builder: (context, snapshot) {
            return CheckboxListTile(
              title: Text(localization.obtained),
              controlAffinity: ListTileControlAffinity.leading,
              value: isObtainedDB(settings),
              onChanged: (value) {
                setObtained(settings, value);
              });}),

现在如何在CheckBoxListTile中使用isObtainedDB中的布尔值?

2 个答案:

答案 0 :(得分:1)

将来的值将在builder函数中保存到snapshot.data,因此,如果从isObtainedDB(settings)返回布尔值,则需要像这样访问它:snapshot.data(函数的值)

FutureBuilder(
  future: isObtainedDB(settings),
  builder: (context, snapshot) {
    return CheckboxListTile(
      title: Text(localization.obtained),
      controlAffinity: ListTileControlAffinity.leading,
      value: snapshot.data, //true or false
      onChanged: (value) {
        setObtained(settings, value);
      }
    );
  }
)

答案 1 :(得分:1)

您可以在下面复制粘贴运行完整代码
我使用5秒的延迟来模拟getItem
步骤1:为避免Future构建器不必要地重建https://github.com/flutter/flutter/issues/11426#issuecomment-414047398

@override
  void initState() {
    _future = isObtainedDB(settings);
    super.initState();
  }
 ... 
body: FutureBuilder(
            future: _future, 

步骤2:选中ConnectionState

switch (snapshot.connectionState) {
        case ConnectionState.none:
          return Text('none');
        case ConnectionState.waiting:
          return Center(child: CircularProgressIndicator()); 

第3步:使用snapshot.data

CheckboxListTile(
                    title: Text("localization.obtained"),
                    controlAffinity: ListTileControlAffinity.leading,
                    value: snapshot.data,

工作演示

enter image description here

完整代码

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  Future<bool> _future;
  Settings settings = Settings();

  Future<Map<String, dynamic>> getItem(String tableName, String id) async {
    await Future.delayed(Duration(seconds: 5), () {});
    /*Database db = await this.db;
    var result = await db.rawQuery(
        "SELECT * FROM $tableName WHERE $colId = $id ORDER BY $colCategory DESC, $colName DESC");
    Map<String, dynamic> singleMap = result[0];*/
    return Future.value(null);
  }

  Future<bool> isObtainedDB(Settings settings) async {
    var map = await getItem("_dbHelper.tblSavedata", "id");
    //var map = Map<String, dynamic>();
    bool obtained = true; //map[_dbHelper.colObtained];
    return obtained;
  }

  @override
  void initState() {
    _future = isObtainedDB(settings);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: FutureBuilder(
            future: _future,
            builder: (context, AsyncSnapshot<bool> snapshot) {
              switch (snapshot.connectionState) {
                case ConnectionState.none:
                  return Text('none');
                case ConnectionState.waiting:
                  return Center(child: CircularProgressIndicator());
                case ConnectionState.active:
                  return Text('');
                case ConnectionState.done:
                  if (snapshot.hasError) {
                    return Text(
                      '${snapshot.error}',
                      style: TextStyle(color: Colors.red),
                    );
                  } else {
                    return CheckboxListTile(
                        title: Text("localization.obtained"),
                        controlAffinity: ListTileControlAffinity.leading,
                        value: snapshot.data,
                        onChanged: (value) {
                          //setObtained(settings, value);
                        });
                  }
              }
            }));
  }
}

class Settings {}