如何让Get方法仅调用一次获取Logo,避免页面重复加载?
解决Flutter页面返回重复调用Get请求加载Logo的问题
你遇到的问题是因为每次返回页面时,页面都会重新初始化,initState会再次执行,导致getLogo被重复调用。下面提供几种可行的解决方案:
方案一:使用AutomaticKeepAliveClientMixin保持页面状态
这个方法可以让页面在切换到后台时不被销毁,从而保证initState只执行一次。
修改你的页面State类:
class _YourPageState extends State<YourPage> with AutomaticKeepAliveClientMixin { bool _loading = false; Map? mapLogo; Future getLogo() async { setState(() { _loading = true; }); http.Response response; response = await http.get( Uri.parse("http://202.51.75.142:706/api_vi/gethospitalinformation/GOK"), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }); setState(() { _loading = false; if (response.statusCode == 200) { mapLogo = json.decode(response.body); } }); } @override void initState() { super.initState(); getData(); // 假设这是你其他的初始化方法 getLogo(); } // 重写这个方法,返回true表示保持状态 @override bool get wantKeepAlive => true; @override Widget build(BuildContext context) { // 必须调用super.build(context),否则状态不会被保持 super.build(context); return Scaffold( // 你的页面布局 body: _loading ? CircularProgressIndicator() : // 显示Logo的组件 ); } }
方案二:缓存Logo数据,仅首次请求
通过在类中添加静态变量缓存已获取的Logo数据,每次调用getLogo前先判断缓存是否存在,存在则直接使用缓存数据,不再发起请求。
修改getLogo方法:
class _YourPageState extends State<YourPage> { bool _loading = false; Map? mapLogo; // 静态变量缓存Logo数据,页面销毁后依然保留 static Map? _cachedLogo; Future getLogo() async { // 如果已有缓存,直接赋值并返回 if (_cachedLogo != null) { setState(() { mapLogo = _cachedLogo; }); return; } setState(() { _loading = true; }); http.Response response; response = await http.get( Uri.parse("http://202.51.75.142:706/api_vi/gethospitalinformation/GOK"), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }); setState(() { _loading = false; if (response.statusCode == 200) { mapLogo = json.decode(response.body); _cachedLogo = mapLogo; // 将数据存入缓存 } }); } @override void initState() { super.initState(); getData(); getLogo(); } // 其他代码... }
方案三:使用单例类管理全局Logo数据
创建一个单例类专门负责Logo数据的获取和存储,确保整个应用中只请求一次数据。
首先创建单例类:
import 'dart:convert'; import 'package:http/http.dart' as http; class LogoManager { // 单例实例 static final LogoManager _instance = LogoManager._internal(); // 存储Logo数据 Map? _logoData; // 工厂构造函数返回单例 factory LogoManager() => _instance; LogoManager._internal(); // 获取Logo数据的方法 Future<Map?> fetchLogo() async { // 已有数据直接返回 if (_logoData != null) return _logoData; final response = await http.get( Uri.parse("http://202.51.75.142:706/api_vi/gethospitalinformation/GOK"), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, ); if (response.statusCode == 200) { _logoData = json.decode(response.body); return _logoData; } return null; } }
然后在页面中使用:
class _YourPageState extends State<YourPage> { bool _loading = false; Map? mapLogo; Future _loadLogo() async { setState(() => _loading = true); // 调用单例类的方法获取Logo final logoData = await LogoManager().fetchLogo(); setState(() { _loading = false; if (logoData != null) mapLogo = logoData; }); } @override void initState() { super.initState(); getData(); _loadLogo(); } // 其他代码... }
以上三种方案都能实现仅调用一次Get请求加载Logo的需求,你可以根据自己的项目架构选择合适的方案。
内容的提问来源于stack exchange,提问作者Mr.Robot
相关产品推荐
相关产品推荐

