How to Use shared_preferences in Flutter with GetX: Save & Retrieve Data Easily

Flutter shared preferences Tutorial

The shared_preferences package is a popular choice for Flutter developers to store and retrieve small amounts of data. This guide will show you how to use shared_preferences with the GetX package to manage state in a Flutter app, following a complete MVC structure.

Why Use shared_preferences in Flutter?

The shared_preferences package allows you to:

  • Store simple data such as strings, integers, booleans, and lists.
  • Save data persistently across app launches.
  • Quickly retrieve values with a straightforward API.


Prerequisites

  1. Flutter SDK: Ensure Flutter is installed.
  2. GetX: Install the get package for state management.
  3. shared_preferences: Add the package to your pubspec.yaml file.
 dependencies:
  flutter:
    sdk: flutter
  get: ^4.6.5
  shared_preferences: ^2.0.15

Run flutter pub get to install the dependencies.


Step 1: Setting up the Controller

We'll create a PreferencesController to handle saving and retrieving values from shared_preferences.

preferences_controller.dart

import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';

class PreferencesController extends GetxController {
  // Observables
  var username = ''.obs;
  var isLoggedIn = false.obs;

  // Method to save username
  Future saveUsername(String name) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString('username', name);
    username.value = name;
  }

  // Method to get username
  Future getUsername() async {
    final prefs = await SharedPreferences.getInstance();
    username.value = prefs.getString('username') ?? '';
  }

  // Method to save login status
  Future saveLoginStatus(bool status) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setBool('isLoggedIn', status);
    isLoggedIn.value = status;
  }

  // Method to get login status
  Future getLoginStatus() async {
    final prefs = await SharedPreferences.getInstance();
    isLoggedIn.value = prefs.getBool('isLoggedIn') ?? false;
  }

  @override
  void onInit() {
    super.onInit();
    getUsername();
    getLoginStatus();
   }
 }

In this controller:

  • Observables: username and isLoggedIn are observable variables.
  • Save & Retrieve Methods: Methods for saving and retrieving values in shared_preferences.
  • onInit: Initializes data retrieval when the controller is loaded.

Step 2: Setting up the View

The view will interact with the controller to display and update saved preferences. We’ll use GetView<PreferencesController> for a clean setup.

preferences_view.dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'preferences_controller.dart';

class PreferencesView extends GetView {
  final TextEditingController nameController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Shared Preferences Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Obx(() => Text(
                  'Welcome, ${controller.username.value}',
                  style: const TextStyle(fontSize: 20),
                )),
            TextField(
              controller: nameController,
              decoration: InputDecoration(labelText: 'Enter Username'),
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                controller.saveUsername(nameController.text);
              },
              child: const Text("Save Username"),
            ),
            const SizedBox(height: 20),
            Obx(() => SwitchListTile(
                  title: const Text('Logged In'),
                  value: controller.isLoggedIn.value,
                  onChanged: (value) {
                    controller.saveLoginStatus(value);
                  },
                )),
           ],
         ),
       ),
     );
   }
 }

In this view:

  • Obx Widgets: Reactive widgets to display the username and isLoggedIn states.
  • TextField: Allows input for the username.
  • Button: Saves the entered username.
  • SwitchListTile: Toggles the login status and saves it.

Step 3: Setting up the Binding

To inject PreferencesController into the view, we’ll create a binding.

preferences_binding.dart

 import 'package:get/get.dart';
 import 'preferences_controller.dart';

 class PreferencesBinding extends Bindings {
  @override
  void dependencies() {
    Get.lazyPut(() => PreferencesController());
  }
 }

Step 4: Running the App

Finally, update main.dart to use the binding and route configuration.

main.dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'preferences_view.dart';
import 'preferences_binding.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      initialRoute: '/',
      getPages: [
        GetPage(
          name: '/',
          page: () => PreferencesView(),
          binding: PreferencesBinding(),
        ),
      ],
      title: 'Shared Preferences Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
    );
  }
 }

Wrapping Up

With the above code:

  1. You’ve set up a PreferencesController to handle saving and retrieving data.
  2. The PreferencesView allows user interaction and updates the UI based on stored values.
  3. Using GetX binding ensures a clean architecture and efficient state management.

The shared_preferences package makes it easy to store simple data types persistently, enhancing the user experience with features like saved usernames and login status. Get started today and take advantage of this powerful combination of shared_preferences and GetX in your Flutter apps!