【问题标题】:How to reload elements after getting data from shared preferences?从共享首选项获取数据后如何重新加载元素?
【发布时间】:2021-09-05 17:32:45
【问题描述】:

我能够从共享偏好中获取数据。我想在重新打开从共享首选项中获取数据的应用程序后重新加载页面上的数据。现在,我试图将数据从共享首选项加载到 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)),
                        ],
                      ),

                    ],
                  ),
                ],
              ),

【问题讨论】:

    标签: flutter sharedpreferences


    【解决方案1】:

    要根据应用程序状态实现逻辑,您必须设置应用程序生命周期事件的观察者并将以下覆盖添加到您的状态类,在您的情况下,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());
    }
    

    此外,从initState 调用setState 毫无意义。 initState 只被调用一次,检查here

    【讨论】:

    • 我正在尝试打印 AppLifecycleState.resumed 但它没有在应用程序上打印。
    • 对不起,我忘了你必须添加观察者才能工作。我现在会更新我的答案。
    • 嗨,我这样做了但是 WidgetsBinding.instance.addObserver(this);正在提示错误“无法无条件调用方法'addObserver',因为接收者可以为'null'。”。(WidgetsBinding.instance?.addObserver(this); 解决了问题)。此外,inActive 和 paused 被调用,只有 resume 不起作用。另外,当我的手机连接到电脑时,我会这样做
    • 在实例之后添加了空检查运算符!,请参阅编辑后的答案。你还需要给你加一行main()函数,也加到answer。
    • 奇怪的是AppLifecycleState.resumed(不是resume!)不起作用。您必须将应用程序置于后台,当再次进入前台时,它应该会触发。尝试打印state,看看你会得到什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-03
    • 2017-09-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多