【问题标题】:Data is showing only after I hot reload or refresh in flutter数据仅在我热重载或刷新后才显示
【发布时间】:2020-04-19 11:46:29
【问题描述】:

在我的数据库中,我有一个用户表,其中存储了用户名和一些标记。当用户转到特定页面时,我想在表格中查看该数据。所以,当我首先进入该页面时,数据(用户名和标记)没有显示。但是,如果我热重载或使用按钮刷新,则数据会正确显示。我的问题是如何在不热重载或使用刷新按钮的情况下做到这一点。这是我的代码:

import 'package:flutter/material.dart';
import 'package:flutter_app/database/db_helper.dart';
import 'package:flutter_app/database/user.dart';

class ViewResult extends StatefulWidget {
 @override
 _ViewResult createState() => _ViewResult();
}

GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey();

class _ViewResult extends State<ViewResult> {
 String tempEmail;
 bool check = true;

 var dbHelper;
 var data = List<User>();

 @override
 void initState() {
   setState(() {
     dbHelper = DBHelper();
     resultData();
   });
   super.initState();
 }

 void resultData() {
     dbHelper.getUser().then((users) {
       for (User temp in users) {
         if (temp.type == "student") data.add(temp);
       }
     });
 }

 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(
       centerTitle: true,
       title: Text("Result"),
     ),
     body: DataTable(
       columnSpacing: 22,
       columns: [
         DataColumn(label: Text("Username")),
         DataColumn(label: Text("Beginner")),
         DataColumn(label: Text("Intermediate")),
         DataColumn(label: Text("Advanced")),
       ],
       rows: data
           .map((user) => DataRow(cells: [
                 DataCell(Text(user.email)),
                 DataCell(Text(user.beginnerMark.toString())),
                 DataCell(Text(user.intermediateMark.toString())),
                 DataCell(Text(user.advancedMark.toString())),
               ]))
           .toList(),
     ),
     backgroundColor: Color.fromRGBO(130, 178, 220, 1),
   );
 }
}

【问题讨论】:

  • 您在 getUser.then 中缺少 setState 调用
  • 对不起,你能解释一下吗?

标签: flutter


【解决方案1】:

您需要setState(() {});。 在resultData函数末尾附近添加:

void resultData() {
  dbHelper.getUser().then((users) {
     for (User temp in users) {
       if (temp.type == "student") data.add(temp);
     }
   setState(() {});
  });

}

更多信息请参见setState

【讨论】:

  • setState()必须从then()内部调用,否则会先执行,完全没有效果。
【解决方案2】:

你必须使用setState 你已经加载了数据并且你的resultData函数正在使用then,这是在initState中的初始setState之后执行的结束了。

@override
void initState() {
  // super.initState(); should be at the start of the method
  super.initState();
  dbHelper = DBHelper();
  resultData();
}

void resultData() {
  dbHelper.getUser().then((users) {
    for (User temp in users) {
      if (temp.type == "student") data.add(temp);
    }
    // since you have already added the results to data
    // setState can have an empty function body
    setState(() {});
  });
}

我更喜欢使用async/await 而不是then,所以我的解决方案如下:

Future<void> resultData() async {
  List<User> users = await dbHelper.getUser();
  setState(() {
    data = users.where((user) => user.type == "student");
  });
}

【讨论】:

    【解决方案3】:

    TLDR:then() 内部调用setState() 如果没有,它将在一切完成之前执行,完全没有效果。

    getUser().then((response) {
       //Your stuff
    
       setState(() {}); //refresh
      });
    

    【讨论】:

    • 这没问题,但这种方法的问题是,它会再次构建整个页面,这会导致性能问题。请尝试使用任何状态管理库来执行此操作。
    • @Mdomerarafat 为了缓解性能问题,创建另一个自定义有状态小部件并在其中使用此代码仅在您需要刷新的小部件上调用 setState
    猜你喜欢
    • 2021-12-02
    • 2018-05-13
    • 2016-10-31
    • 2013-07-12
    • 2021-10-30
    • 2018-04-26
    • 2021-02-06
    • 2021-04-10
    • 2022-01-02
    相关资源
    最近更新 更多