Flutter carousel_slider首次启动图片不显示,热重载后正常怎么解决?
问题根因
- 你在
initState中调用的getapidata是异步网络请求方法,Flutter不会等待请求完成再执行build方法渲染页面,首次渲染时imageList是空数组,轮播组件没有内容可以显示 - 网络请求成功获取到图片链接后,你仅修改了
imageList的值,没有调用setState方法通知Flutter刷新UI,因此页面不会自动更新;热重载会强制触发页面重建,此时数据已经加载完成,所以能正常显示图片 - 全局变量存储页面状态的方式不符合StatefulWidget的开发规范,后续迭代容易出现数据错乱的问题
解决方案
你提到的if/else条件判断确实可以解决该问题,配合状态刷新就能实现首次启动正常显示的效果,修改步骤如下:
- 将全局定义的
imageList变量移到_MyAppState类内部,新增isLoading加载状态变量 - 网络请求完成后调用
setState更新状态,通知Flutter重新渲染页面 - 在轮播组件渲染位置添加条件判断,加载中显示进度占位,加载完成后再渲染轮播
修改后的核心代码如下:
首先是状态变量定义部分:
class _MyAppState extends State<MyApp> { String cevap = ""; late Apianaekran _apianaekran; late Result _result; List imageList = []; // 原全局变量移到状态类内部 bool isLoading = true; // 新增加载状态标记 get Index => null;
然后修改getapidata方法,请求完成后更新状态:
Future<void> getapidata() async { String url = "https://www.mobilonsoft.com/fpsapi/default.aspx?op=application_initialization_customer&firmuid=feedmekktc&device_id=web_20210813180900001&device_platform=4&lang=en"; Response responsee = await get(Uri.parse(url)); if (responsee.statusCode == 200) { Map cevapjson = jsonDecode(responsee.body); Apianaekran ekran = Apianaekran.fromJson(cevapjson); int ct = ekran.result.sliderImages.length; for(int i=0; i<ct; i++){ imageList.add(ekran.result.sliderImages[i].imageUrl); } } else { print("bir sorun oluştu"); } // 调用setState触发UI重绘 setState(() { isLoading = false; }); }
最后修改轮播组件部分的代码,添加条件判断:
Container( constraints: const BoxConstraints.expand(height: 200), child: isLoading // 加载中显示进度指示器 ? const Center(child: CircularProgressIndicator(color: Colors.red)) // 加载完成后显示轮播 : CarouselSlider( options: CarouselOptions( enlargeCenterPage: true, enableInfiniteScroll: true, autoPlay: true ), items: imageList.map((e) => ClipRRect( borderRadius: BorderRadius.circular(8), child: Image.network( e, width: 1050, height: 350, fit: BoxFit.cover, ), )).toList() ) ),
内容的提问来源于stack exchange,提问作者Arda Özdiker
相关产品推荐
相关产品推荐

