Auvee
Auvee

Reputation: 429

How can I preserve the state or data even after I close app using Flutter BloC?

I can't save the state or data after stopping the application, which is the issue. Even after I close the app, I want it to retain my previous data or state. In what way can I accomplish that?

For state management, I am using Flutter Bloc. For your better understanding, below is my dummy code. Here, even after I close the application, I want to preserve the current state. However, I'm unable to get back the info or current state that I was browsing before I close the program.

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: BlocProvider(
        create: (context) => LocationBloc(),
        child: HomeScreen(),
      ),
    );
  }
}

class LocationBloc extends Bloc<LocationEvent, LocationState> {
  LocationBloc() : super(null);

  @override
  Stream<LocationState> mapEventToState(LocationEvent event) async* {
    switch (event) {
      case LocationEvent.selectGPS:
        yield GPSState();
        break;
      case LocationEvent.selectLocation:
        yield LocationState();
        break;
    }
  }
}

class GPSState extends LocationState {}

class LocationState extends LocationState {}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final LocationBloc _locationBloc = BlocProvider.of<LocationBloc>(context);

    return Scaffold(
      appBar: AppBar(
        title: Text('Home'),
      ),
      body: BlocBuilder<LocationBloc, LocationState>(
        builder: (context, state) {
          return Center(
            child: Text(
              state.runtimeType == GPSState ? 'GPS' : 'Location',
              style: TextStyle(fontSize: 24),
            ),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => SettingsScreen()),
          );
        },
        child: Icon(Icons.settings),
      ),
    );
  }
}

class SettingsScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final LocationBloc _locationBloc = BlocProvider.of<LocationBloc>(context);

    return Scaffold(
      appBar: AppBar(
        title: Text('Settings'),
      ),
      body: BlocBuilder<LocationBloc, LocationState>(
        builder: (context, state) {
          return Column(
            children: [
              RadioListTile(
                title: Text('GPS'),
                value: GPSState(),
                groupValue: state,
                onChanged: (value) {
                  _locationBloc.add(LocationEvent.selectGPS);
                },
              ),
              RadioListTile(
                title: Text('Location'),
                value: LocationState(),
                groupValue: state,
                onChanged: (value) {
                  _locationBloc.add(LocationEvent.selectLocation);
                },
              ),
            ],
          );
        },
      ),
    );
  }
}

Upvotes: 3

Views: 466

Answers (1)

Ramon Farizel
Ramon Farizel

Reputation: 185

This is how I'd tackle this challenge.

1 Get the app lifecycle.

class _AppLifecycleReactorState extends State with WidgetsBindingObserver {

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

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

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    print("App Lifecycle State : $state");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold();
  }
}

2 - You can use the shared_preferences package to persist data across app launches.

Here's an example:

import 'package:shared_preferences/shared_preferences.dart';

void storeData() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  await prefs.setString('key', 'value');
}

Then, when your app starts up again, you can load the stored data like this:

void loadData() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  String value = prefs.getString('key');
}

3 - Write your data when the AppLifecycle changes and Read from preferences when opening the app.


Heads up:

certain situations (like when the OS forcefully closes your app), you may not have enough time to reliably save data to disk.

Upvotes: 0

Related Questions