0

I am able to fetch data from shared preferences. I want to reload the data on the page after reopening the app fetching data from shared preferences. Right now, im trying to load data from shared preferences to a list which is called in the initState().

Note:- when i navigate to other page and come page to page on which data needs to be updated. The data is updated successfully. But i want to do this everytime app is opened again

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);

  }
  }

}

}
  

Im trying to update text for which i have made another stateful widget(Text is not updating even after saving data to a global list and fetching data on resumed)

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)),
                        ],
                      ),

                    ],
                  ),
                ],
              ),
Atharv Sharma
  • 125
  • 2
  • 8

1 Answers1

0

To implement logic depending on application state you have to setup observer to application life cycle events and add the following override to your state class, in your case AppLifecycleState.resumed is the one that you need to monitor:

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
  }
}

Include this line in your main() function, this will ensure that you can safely use WidgetsBinding.instance!:

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

Furthermore, there is no point calling setState from initState. initState is only called once, check here.

Peter Koltai
  • 8,296
  • 2
  • 10
  • 20
  • Im trying to print AppLifecycleState.resumed but it is not printing on the app. – Atharv Sharma Sep 06 '21 at 16:20
  • Sorry, I forgot that you have to add observer for this to work. I will update my answer right now. – Peter Koltai Sep 06 '21 at 16:33
  • Hi, I did that however WidgetsBinding.instance.addObserver(this); is prompting an error "The method 'addObserver' can't be unconditionally invoked because the receiver can be 'null'.".(WidgetsBinding.instance?.addObserver(this); solves the issue). Moreover, inActive and paused are being called only resume is not working. Also, im doing this when my phone is connected to pc – Atharv Sharma Sep 06 '21 at 17:34
  • Added the null-check operator `!` after instance, see edited answer. You also need to add a line to you `main()` function, also added to answer. – Peter Koltai Sep 06 '21 at 17:52
  • It is strange that `AppLifecycleState.resumed` (it is not `resume`!) is not working. You have to put the app to background and when it comes to foreground again, it should fire. Try printing `state` and see what you get. – Peter Koltai Sep 06 '21 at 18:10
  • Thanks, resumed is now being called and my data fetched from sharedpreferences is being printed on resume. However, data on my screen is still not being updated. What im doing is i have a global list in which im saving my dataModel and on resume im fetching that data from shared preferences back to the global list. my example of data not updating is Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(locationList.length != 0 ? locationList[widget.index].temperature : "--\u2103")) – Atharv Sharma Sep 06 '21 at 18:23
  • Please update your code and show what do you do on resume. – Peter Koltai Sep 06 '21 at 18:27
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/236821/discussion-between-atharv-sharma-and-peter-koltai). – Atharv Sharma Sep 06 '21 at 18:31