首页 > 解决方案 > 从共享首选项获取数据后如何重新加载元素?

问题描述

我能够从共享首选项中获取数据。我想在重新打开从共享首选项中获取数据的应用程序后重新加载页面上的数据。现在,我试图将数据从共享首选项加载到在 initState() 中调用的列表中。

注意:- 当我导航到其他页面并逐页访问需要更新数据的页面时。数据更新成功。但我想每次再次打开应用程序时都这样做

class WeatherApp extends StatefulWidget {
  const WeatherApp({Key? key}) : super(key: key);
  static const String idScreen = "weather";

  @override
  _WeatherAppState createState() => _WeatherAppState();
}



class _WeatherAppState extends State<WeatherApp> {

  final preferenceService = PreferencesService();

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance!.addObserver(this);

  }

  @override
  void dispose() {
    WidgetsBinding.instance!.removeObserver(this);
    super.dispose();
  }
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    print('state = $state');

    if (state == AppLifecycleState.resumed){
      setState(() {
        preferenceService.getData();
      });

    }

}




class PreferencesService{

void saveData(List<dynamic> data) async{
  final preferences = await SharedPreferences.getInstance();
 
  String encodedData = jsonEncode(data);

  await preferences.setString("weather_data", encodedData);

}

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"],
          )
      );
      print("fetching Data");
      print(locationList);

  }
  }

}

}
  

我正在尝试更新我制作了另一个有状态小部件的文本(即使在将数据保存到全局列表并在恢复时获取数据之后,文本也没有更新)

Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      Text(locationList.length != 0 ? locationList[widget.index].temperature : "--\u2103"),
      Row(
          children: [ 
SvgPicture.asset(locationList.length != 0 ? locationList[widget.index].iconUrl : "assets/rain.svg", width: 30,height: 30,color: Colors.white,),
             Text(locationList.length != 0 ? locationList[widget.index].weatherType : "Rainy",style: GoogleFonts.openSans(fontSize: 20,fontWeight: FontWeight.bold,color: Colors.white)),
                        ],
                      ),

                    ],
                  ),
                ],
              ),

标签: fluttersharedpreferences

解决方案


要根据应用程序状态实现逻辑,您必须设置应用程序生命周期事件的观察者并将以下覆盖添加到您的状态类,在您的情况下AppLifecycleState.resumed是您需要监控的:

class _MyWidgetState extends State<MyWidget> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance!.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance!.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    // possible values of state:
    // AppLifecycleState.inactive
    // AppLifecycleState.detached
    // AppLifecycleState.paused
    // AppLifecycleState.resumed
  }
}

在你的函数中包含这一行main(),这将确保你可以安全地使用WidgetsBinding.instance!

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(App());
}

setState此外,从调用没有意义initStateinitState只调用一次,请在此处查看


推荐阅读