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

Flutter:解决Future Builder进度条卡顿及网格无刷新问题

Flutter问题解决方案

问题1:FutureBuilder加载时进度条卡顿

问题根源

每次build执行时都会重新调用getDataLocally创建新的Future,导致JSON解析重复执行,占用主线程资源,进而阻塞进度条动画。

修复步骤

  1. 在State中添加变量存储Future实例
  2. 在initState中初始化Future,确保仅执行一次
  3. 更新FutureBuilder使用缓存的Future

问题2:返回主页后网格不自动更新

问题根源

从测验页面返回时,HomePage未主动读取SharedPreferences中的最新等级,导致UI状态未同步;使用pushReplacement重建页面会引发不必要的UI重绘,造成卡顿。

修复步骤

  1. 跳转测验页面时使用Navigator.push的then回调
  2. 在回调中重新加载SharedPreferences的等级数据并调用setState更新UI

修改后的完整代码

import 'package:flashcards_quiz/models/model.dart';
import 'package:flashcards_quiz/util/theme.dart';
import 'package:flashcards_quiz/views/flashcard_screen.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

class HomePage extends StatefulWidget {
  const HomePage({super.key});
  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  late int level;
  late Future<List<Quiz>> _quizDataFuture; // 缓存Future实例,避免重复执行

  @override
  void initState() {
    super.initState();
    _loadsts();
    _quizDataFuture = getDataLocally(context); // 仅初始化一次异步请求
  }

  _loadsts() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    var newlevel = prefs.getInt('level') ?? 1;
    setState(() {
      level = newlevel;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: backgroundColor,
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.only(top: 0, left: 15, right: 15),
          child: ListView(
            physics: const BouncingScrollPhysics(),
            children: [
              const SizedBox(height: 20),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Text(
                    'List',
                    style: Theme.of(context).textTheme.bodySmall!.copyWith(
                          color: Colors.white,
                          fontSize: 18,
                          fontWeight: FontWeight.w900,
                        ),
                  ),
                ],
              ),
              const SizedBox(height: 5),
              const Divider(color: Colors.grey),
              FutureBuilder<List<Quiz>>(
                future: _quizDataFuture, // 使用缓存的Future实例
                builder: (context, snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return Center(
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: const [
                          CircularProgressIndicator(
                            valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
                            strokeWidth: 4.0,
                          ),
                          SizedBox(height: 16),
                          Text(
                            "Loading ... ",
                            style: TextStyle(
                              color: Colors.white,
                              fontSize: 25,
                              fontWeight: FontWeight.bold,
                              fontStyle: FontStyle.italic,
                            ),
                          )
                        ],
                      ),
                    );
                  } else if (snapshot.hasError) {
                    return Text('Error: ${snapshot.error}');
                  } else {
                    final data = snapshot.data!;
                    return GridView.builder(
                      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                        crossAxisCount: 3,
                        mainAxisSpacing: 10,
                        crossAxisSpacing: 10,
                        childAspectRatio: 0.85,
                      ),
                      shrinkWrap: true,
                      physics: const BouncingScrollPhysics(),
                      itemCount: data.length,
                      itemBuilder: (context, index) {
                        final topicsData = data[index];
                        return GestureDetector(
                          onTap: () {
                            if (level >= index + 1) {
                              // 跳转后监听返回事件,刷新等级
                              Navigator.push(
                                context,
                                MaterialPageRoute(
                                  builder: (context) => NewCard(
                                    level: index + 1,
                                    questions: topicsData.questions,
                                    name: topicsData.name,
                                  ),
                                ),
                              ).then((_) {
                                // 返回主页后重新加载最新等级
                                _loadsts();
                              });
                            } else {
                              ScaffoldMessenger.of(context).showSnackBar(
                                SnackBar(content: Text('Please Complete Level $level')),
                              );
                            }
                          },
                          child: Card(
                            color: level >= index + 1 ? unlockedBg : lockedBg,
                            elevation: 10,
                            shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.circular(10),
                            ),
                            child: Center(
                              child: Column(
                                mainAxisAlignment: MainAxisAlignment.center,
                                crossAxisAlignment: CrossAxisAlignment.center,
                                children: [
                                  Icon(
                                    level >= index + 1 ? unlocked : locked,
                                    color: Colors.white,
                                    size: 55,
                                  ),
                                  const SizedBox(height: 15),
                                  Text(
                                    'Level  ${index + 1}',
                                    textAlign: TextAlign.center,
                                    style: Theme.of(context).textTheme.headlineSmall!.copyWith(
                                          fontSize: 18,
                                          color: Colors.white,
                                          fontWeight: FontWeight.w600,
                                        ),
                                  )
                                ],
                              ),
                            ),
                          ),
                        );
                      },
                    );
                  }
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Future<List<Quiz>> getDataLocally(BuildContext context) async {
  final assetBundle = DefaultAssetBundle.of(context);
  final data = await assetBundle.loadString('assets/data.json');
  final reportData = quizFromJson(data);
  return reportData;
}

内容的提问来源于stack exchange,提问作者dev.skas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 18:44:51