更新FutureBuilder ListView后,Flutter UI未发生变化?

np8igboo  于 2023-01-21  发布在  Flutter
关注(0)|答案(1)|浏览(168)

我有两个屏幕,主页和添加屏幕。应用程序在主页上启动,有一个浮动操作按钮和一个FutureBuilder。点击FAB按钮,它会转到添加屏幕,在那里我可以为另一个条目添加细节。提交时,数据被保存在sqlite数据库中并返回到主页。2但是即使调用setState,FutureBuilder列表也不会重建。我确信数据库在条目创建时更新,但未反映在UI中?
任何代码改进建议也是受欢迎的!
这是我的主页.dart代码

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  Future<List<Model>> getData() async {
    return await DatabaseHelper.instance.getModels();
  }

  Future? userFuture;

  @override
  void initState() {
    super.initState();
    userFuture = getData();
  }

  @override
  Widget build(BuildContext context) {
    print('Building listview');
    return Center(
      child: FutureBuilder<List<Model>>(
        future: userFuture as Future<List<Model>>,
        builder: ((context, AsyncSnapshot<List<Model>> snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.waiting:
              return const CircularProgressIndicator();
            default:
              if (snapshot.data!.isEmpty) {
                return Text('No data present');
              } else if (snapshot.hasData) {
                return ListView.builder(
                  itemCount: snapshot.data?.length,
                  itemBuilder: ((context, index) {
                    return MyCard(
                        key: ValueKey(snapshot.data![index].id),
                        snapshot.data![index].id,
                        snapshot.data![index].title,
                        snapshot.data![index].purpose);
                  }),
                );
              }
              return Text('data');
          }
        }),
      ),
    );
  }
}

下面是我的Add.dart屏幕:

class AddEntry extends StatefulWidget {
  const AddEntry({super.key});

  @override
  State<AddEntry> createState() => _AddEntryState();
}

class _AddEntryState extends State<AddEntry> {
  final GlobalKey<FormState> _key = GlobalKey<FormState>();
  Map<String, String?> formField = <String, String?>{};

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('New Entry'),
      ),
      body: Form(
        key: _key,
        child: Column(
          children: [
            Flexible(
              child: MyTextField('Title', callback),
            ),
            Flexible(
              child: MyTextField('Purpose', callback),
            ),
            Flexible(
              child: MyTextField('Password', callback, obscure: true),
            ),
            TextButton(
              onPressed: () async {
                if (_key.currentState!.validate()) {
                  _key.currentState?.save();
                  formField.forEach((label, value) => print('$label = $value'));
                  await DatabaseHelper.instance.insertModel(Model(
                      id: null,
                      title: formField['Title'],
                      purpose: formField['Purpose'],
                      lastAccess: DateTime.now().toString(),
                      dateAdded: DateTime.now().toString(),
                      password: formField['Password']));
                  print(await DatabaseHelper.instance.getModels());
                  // await DatabaseHelper.instance.deleteAllData();
                  // print(await DatabaseHelper.instance.getModels());
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(
                      content: Text('Data Saved!'),
                      action: SnackBarAction(
                        label: 'Edit',
                        onPressed: () {
                          print('edit pressed!');
                        },
                      ),
                    ),
                  );
                  setState(() {
                    Navigator.pop(context);
                  });
                  //add logic to rebuild home screen after every addition of entry
                }
              },
              child: Text('Submit'),
            ),
          ],
        ),
      ),
    );
  }

  callback(varLabel, varValue) {
    formField[varLabel] = varValue;
  }
}

class MyTextField extends StatelessWidget {
  final String label;
  final bool obscure;
  final String? Function(String?) validation;
  final Function callback;

  const MyTextField(this.label, this.callback,
      {super.key, this.obscure = false, this.validation = validateText});

  @override
  Widget build(BuildContext context) {
    return TextFormField(
      decoration: InputDecoration(
        labelText: label,
      ),
      validator: validation,
      obscureText: obscure,
      onSaved: ((String? val) => callback(label, val)),
    );
  }
}

String? validateText(String? formText) {
  if (formText!.isEmpty) return 'Field is required!';

  return null;
}

String? validateEmail(String? formEmail) {
  if (formEmail!.isEmpty) return 'E-Mail Address is required!';

  String pattern = r'\w+@\w+\.\w+';
  RegExp regexp = RegExp(pattern);
  if (!regexp.hasMatch(formEmail)) return 'Invalid E-Mail Address format!';

  return null;
}

String? validatePassword(String? password) {
  if (password!.isEmpty) return 'Password can\'t be empty!';

  String pattern =
      r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!@#\$&*~]).{8,}$';
  RegExp regexp = RegExp(pattern);
  if (!regexp.hasMatch(password)) {
    return 'Password must be atleast 8 characters, include an uppercase letter, number and symbol';
  }

  return null;
}
kh212irz

kh212irz1#

像这样将getData()直接放入Future.builder()

Center(
      child: FutureBuilder<List<Model>>(
        future:getData(), <---------------------------------------- Make here change.
        builder: ((context, AsyncSnapshot<List<Model>> snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.waiting:
              return const CircularProgressIndicator();
            default:
              if (snapshot.data!.isEmpty) {
                return Text('No data present');
              } else if (snapshot.hasData) {
                return ListView.builder(
                  itemCount: snapshot.data?.length,
                  itemBuilder: ((context, index) {
                    return MyCard(
                        key: ValueKey(snapshot.data![index].id),
                        snapshot.data![index].id,
                        snapshot.data![index].title,
                        snapshot.data![index].purpose);
                  }),
                );
              }
              return Text('data');
          }
        }),
      ),
    );

相关问题