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

Flutter从SharedPreferences获取数据后如何刷新页面UI元素?

问题原因

你的代码存在3个核心问题导致UI无法在应用切回时自动更新:

  1. _WeatherAppState 没有混入 WidgetsBindingObserver 接口,应用生命周期状态变更的监听根本不会生效
  2. getData() 是异步函数,你直接在 setState() 中调用它时,setState 执行完成后异步拉取数据的逻辑才会执行,全局列表更新后没有再次触发UI重绘
  3. 你使用全局列表存储数据,子组件没有监听该列表的变更,就算列表内容更新,子组件也不知道需要刷新自身UI
修复步骤

1. 补全生命周期监听的混入

修改 _WeatherAppState 类的定义,混入生命周期监听接口:

class _WeatherAppState extends State<WeatherApp> with WidgetsBindingObserver {
  // 保留你原有类内的所有代码即可
}

2. 改造异步逻辑调用顺序

首先修改 PreferencesService 中的 getData 方法,让它返回 Future 方便等待执行完成:

// 修改方法返回值为Future<void>
Future<void> getData() async{
  final preferences = await SharedPreferences.getInstance();
  var jsonData = preferences.getString("weather_data");
  if (jsonData == null){
    locationList = [];
  } else{
    locationList.clear();
    var dataList = json.decode(jsonData);
    for (var e in dataList) {
      locationList.add(
          WeatherModel(
            weatherId: e["weatherId"],
            cityId: e["cityId"],
            city: e["city"],
            dateTime: e["dateTime"],
            temperature: e["temperature"],
            weatherType: e["weatherType"],
            iconUrl: e["iconUrl"],
            wind: e["wind"],
            rain: e["rain"],
            humidity: e["humidity"],
          )
      );
    }
  }
}

再修改生命周期回调的逻辑,等数据拉取完成后再触发状态更新:

@override
void didChangeAppLifecycleState(AppLifecycleState state) async {
  print('state = $state');
  if (state == AppLifecycleState.resumed){
    // 等待SharedPreferences数据拉取完成
    await preferenceService.getData();
    // 确认当前页面未销毁后触发UI重绘
    if(mounted) setState(() {});
  }
}

3. 让子组件自动响应列表变更(可选,更稳定)

如果执行完前两步子组件依然没有更新,说明全局列表的变更没有触发子组件的重绘,用 ValueNotifier 改造全局列表即可:
首先修改全局 locationList 的定义:

// 替换你原来的locationList定义
ValueNotifier<List<WeatherModel>> locationList = ValueNotifier([]);

同步修改 getData 方法中操作列表的逻辑:

Future<void> getData() async{
  final preferences = await SharedPreferences.getInstance();
  var jsonData = preferences.getString("weather_data");
  if (jsonData == null){
    locationList.value = [];
  } else{
    List<WeatherModel> newList = [];
    var dataList = json.decode(jsonData);
    for (var e in dataList) {
      newList.add(
          WeatherModel(
            weatherId: e["weatherId"],
            cityId: e["cityId"],
            city: e["city"],
            dateTime: e["dateTime"],
            temperature: e["temperature"],
            weatherType: e["weatherType"],
            iconUrl: e["iconUrl"],
            wind: e["wind"],
            rain: e["rain"],
            humidity: e["humidity"],
          )
      );
    }
    locationList.value = newList;
  }
}

最后用 ValueListenableBuilder 包裹你原有子组件的UI代码,自动监听列表变更刷新:

ValueListenableBuilder<List<WeatherModel>>(
  valueListenable: locationList,
  builder: (context, list, child) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(list.isNotEmpty ? list[widget.index].temperature : "--℃"),
        Row(
          children: [ 
            SvgPicture.asset(list.isNotEmpty ? list[widget.index].iconUrl : "assets/rain.svg", width: 30,height: 30,color: Colors.white,),
            Text(list.isNotEmpty ? list[widget.index].weatherType : "Rainy",style: GoogleFonts.openSans(fontSize: 20,fontWeight: FontWeight.bold,color: Colors.white)),
          ],
        ),
      ],
    );
  }
)

内容的提问来源于stack exchange,提问作者Atharv Sharma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 13:57:05