You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Widget构建前将sqflite数据预加载到变量中?

解决方案

核心修改逻辑

  • 新增加载状态标记规避空值报错:在State类中添加_isDataLoaded布尔变量标记数据加载状态,build阶段优先判断状态,未加载完成时展示占位内容,不会直接访问null的data变量触发异常。
  • 数据加载完成后主动触发UI更新:异步方法loadData拿到数据库返回结果后调用setState,仅触发一次页面重建更新UI,后续动画导致的页面重建不会重新走数据库读取逻辑,也不会出现加载进度条。
  • 动画重建优化:可以将执行进度条动画的模块拆分为独立的StatefulWidget,动画状态更新仅触发自身重建,不会带动整个父页面重绘,进一步减少不必要的性能消耗。

修改后可运行代码

import 'package:flutter/material.dart';
import 'package:phonica/sql/service.dart';

class Testing extends StatefulWidget {
  const Testing({Key? key}) : super(key: key);

  @override
  State<Testing> createState() => _TestingState();
}

class _TestingState extends State<Testing> with TickerProviderStateMixin {
  final _databaseService = DatabaseService();
  var data;
  // 新增加载状态标记
  bool _isDataLoaded = false;

  @override
  void initState() {
    super.initState();
    loadData();
  }

  loadData() async {
    var cramModel = await _databaseService.readDatabaseTable();
    // 加载完成后调用setState更新状态
    setState(() {
      data = cramModel[1];
      _isDataLoaded = true;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.indigo[50],
      body: Container(
        child: LayoutBuilder(
          builder: (BuildContext context, BoxConstraints constraints) {
            return Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Center(
                  // 加载完成前展示占位文本,也可以放空的Container
                  child: _isDataLoaded ? Text(
                    data["WORD_EN"],
                  ) : const Text("加载中..."),
                ),
              ],
            );
          },
        ),
      ),
    );
  }
}

可选:FutureBuilder正确用法(避免重复显示加载动画)

如果你后续还是想使用FutureBuilder,只要把Future对象提前存在State中,不要在build方法里直接生成新的Future即可,已完成的Future不会重新触发加载逻辑:

// 仅展示修改部分代码
class _TestingState extends State<Testing> with TickerProviderStateMixin {
  final _databaseService = DatabaseService();
  late Future _dataFuture; // 提前声明Future变量

  @override
  void initState() {
    super.initState();
    _dataFuture = loadData(); // initState中仅初始化一次Future
  }

  loadData() async {
    var cramModel = await _databaseService.readDatabaseTable();
    return cramModel[1];
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _dataFuture, // 复用同一个Future对象,不会重复加载
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          return Text(snapshot.data["WORD_EN"]);
        }
        return const Text("加载中...");
      }
    );
  }
}

内容的提问来源于stack exchange,提问作者Ian Rajkumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 00:36:04