Flutter:解决Future Builder进度条卡顿及网格无刷新问题
Flutter问题解决方案
问题1:FutureBuilder加载时进度条卡顿
问题根源
每次build执行时都会重新调用getDataLocally创建新的Future,导致JSON解析重复执行,占用主线程资源,进而阻塞进度条动画。
修复步骤
- 在State中添加变量存储Future实例
- 在
initState中初始化Future,确保仅执行一次 - 更新FutureBuilder使用缓存的Future
问题2:返回主页后网格不自动更新
问题根源
从测验页面返回时,HomePage未主动读取SharedPreferences中的最新等级,导致UI状态未同步;使用pushReplacement重建页面会引发不必要的UI重绘,造成卡顿。
修复步骤
- 跳转测验页面时使用
Navigator.push的then回调 - 在回调中重新加载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
相关产品推荐
相关产品推荐

