【问题标题】:How to load data from file in one stateful class and use it in another stateful class in flutter?如何从一个有状态类中的文件加载数据并在颤动中的另一个有状态类中使用它?
【发布时间】:2019-10-24 17:47:53
【问题描述】:

我是 Flutter 的新手。我有一个 dart 文件“CreateDatabase.dart”,它应该从 csv 文件中获取数据并存储在一个变量中。在另一个文件“main.dart”中,我想访问此变量以使用获取的数据。 “CreateDatabase.dart”文件如下所示:

class CreateDatabase extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    return CreateDatabaseState();
  }
}

class CreateDatabaseState extends State<CreateDatabase> {
  @override
  void initState(){
    super.initState();
    fetchVenueDatabase();

  }
  List<List<dynamic>> venueDB;
  List<Buildings> buildings;

  List<Buildings> getBuildings(){
    return this.buildings;
  }

  Future<String> _loadVenueDatabase() async {
    return await rootBundle.loadString('assets/VenueDatabase.csv');
  }

  Future<List<List<dynamic>>> loadVenuedatabase() async {
    String data = await _loadVenueDatabase();
    List<List<dynamic>> rowsAsListOfValues = const CsvToListConverter().convert(data);
    return rowsAsListOfValues;
  }

 fetchVenueDatabase() async{
    venueDB = await loadVenuedatabase();
    ......
    //manipulating venueDB and storing its value in this.buildings
    ......
    this.buildings = buildings;
 }

 @override
  Widget build(BuildContext context) {
    return null;
  }
}

main.dart 文件如下所示:

void main() {
  runApp(MyApp());
}
class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _MyAppState();
  }
}

class _MyAppState extends State<MyApp> {

  static List<Buildings> allBuildings;

  @override
  void initState() {            //Initial State of the app
    super.initState();
    CreateDatabaseState cr = CreateDatabaseState();
    allBuildings = cr.getBuildings();
  }

  @override
  Widget build(BuildContext context) {
    ....
  }
}

但是main中的getter方法,

allBuildings= cr.getBuildings();

总是返回 null。我哪里错了?

【问题讨论】:

  • 这是一种反模式。你不应该那样做。相反,您应该有一个有状态的小部件来存储数据,它是所有需要它的小部件的祖先。

标签: flutter dart


【解决方案1】:

您不应该为此使用小部件。只需创建一个普通类并在那里定义您的方法。

class Database {
}
  List<List<dynamic>> venueDB;
  List<Buildings> buildings;

  List<Buildings> getBuildings(){
    return this.buildings;
  }

  Future<String> _loadVenueDatabase() async {
    return await rootBundle.loadString('assets/VenueDatabase.csv');
  }

  Future<List<List<dynamic>>> loadVenuedatabase() async {
    String data = await _loadVenueDatabase();
    List<List<dynamic>> rowsAsListOfValues = const CsvToListConverter().convert(data);
    return rowsAsListOfValues;
  }

 fetchVenueDatabase() async{
    venueDB = await loadVenuedatabase();
    ......
    //manipulating venueDB and storing its value in this.buildings
    ......
    this.buildings = buildings;
 }
}

然后在你的主类中简单明了。

Database db = Database();
allBuildings = db.getBuildings();

然后你需要在 db.getBuildings() 之前加载场地或者做一些异步的东西。但这应该很容易做到。一种选择是使 main() 方法异步并等待某种数据加载。您可以将场地数据库列表设为静态,以便它独立于数据库对象保存数据。

这样你可以调用:Database.fetchVenueData(),然后它必须使用静态列表,当然本身也是静态的。

Future main() async {
   await Database.fetchVenueData();
   runApp(MyApp());
}

以及修改后的数据库类:

 static List<List<dynamic>> venueDB;

 static Future<void> fetchVenueDatabase() async{
    venueDB = await loadVenuedatabase();
    ......
    //manipulating venueDB and storing its value in this.buildings
    ......
    Database.buildings = buildings;
 }

但还有更多选择。

免责声明:我没有编译该代码。所以也许有一个缺失的部分或其他东西,但你应该明白这一点。

Disclaimer2:静态变量有点糟糕。所以明智地使用它们。他们不会收集垃圾,但我认为只要您的应用程序正在运行,这些 CSV 数据就应该驻留在内存中。如果不是这种情况,还有更好的选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-07
    • 2021-12-18
    • 1970-01-01
    • 2018-03-14
    • 1970-01-01
    • 2019-10-06
    • 2021-01-01
    • 1970-01-01
    相关资源
    最近更新 更多