Home > Net >  I'm having issues using Shared Preferences on another page
I'm having issues using Shared Preferences on another page

Time:02-23

I have been having issues retrieving the "username" String saved in Shared Preferences (from the Settings page) for the home page text field (~Line 60 main.dart). I have tried a few methods to retrieve it, but so far I haven't had any luck with trying to grab it. The last attempt I tried was using '$user' (~Line 29), but I still haven't had any luck. I'm still very new to Flutter programming, but I had assumed you could access Shared Preferences data globally as long as you had the Key. So far when I tried using the methods I saw online and in documentation I had no luck transferring the data. Thank you for your help!

main.dart

import 'package:bit/shared_preferences.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:bit/saved_data.dart';

void main() {
  runApp(MaterialApp(
    title: 'App',
    themeMode: ThemeMode.system,
    theme: MyThemes.lightTheme,
    darkTheme: MyThemes.darkTheme,
    home: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final theme = MediaQuery.of(context).platformBrightness == Brightness.dark
        ? 'Dark Theme'
        : 'Light Theme';
    final user = ''; // Empty String Line 29

    var scaffold = Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
      ),
// Body Home Page Beginning
      body: SingleChildScrollView(
          child: Center(
        child: Text('Hello $theme!'),
      )),
// Body Home Page End
      drawer: Drawer(
        // Drawer Beginning
        child: ListView(
          children: [
// Drawer Header
            DrawerHeader(
              decoration: const BoxDecoration(
                color: Colors.blue,
              ),
              child: Stack(
                children: const [
                  Align(
                      alignment: Alignment.centerLeft,
                      child: CircleAvatar(
                        backgroundColor: Colors.white,
                        radius: 50.0,
                      )),
                  Align(
                      alignment: Alignment.centerRight,
                      child: Text('$user',             // Area To Input Text Line 60
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 20.0,
                        ),
                      )),
                  Align(
                      alignment: Alignment(1, 0.3),
                      child: Text(
                        'Supporter',
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 15.0,
                        ),
                      ))
                ],
              ),
            ),
// Drawer List
            ListTile(
              title: const Text('Settings'),
              subtitle: const Text('Account Info & Settings'),
              onTap: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => Settings()),
                );
              },
              trailing: const Icon(Icons.arrow_forward_ios_rounded),
            ),
          ],
        ),
      ),
// Drawer End
    );
    return MaterialApp(
      title: 'App',
      themeMode: ThemeMode.system,
      theme: MyThemes.lightTheme,
      darkTheme: MyThemes.darkTheme,
      home: scaffold,
    );
  }
}

// Settings Page & Account Information
class Settings extends StatefulWidget {
  Settings({Key? key}) : super(key: key);

  @override
  State<Settings> createState() => _SettingsState();
}

class _SettingsState extends State<Settings> {
  final _preferencesService = PreferencesService();
  final _usernameController = TextEditingController();
  void initState() {
    super.initState();
    _populateFields();
  }

  void _populateFields() async {
    final settings = await _preferencesService.getSettings();
    setState(() {
      _usernameController.text = settings.username;
    });
  }

  @override
  Widget build(BuildContext context) {
    final theme = MediaQuery.of(context).platformBrightness == Brightness.dark
        ? 'Dark Theme'
        : 'Light Theme';

    return Scaffold(
        appBar: AppBar(
          title: const Text(
              'Settings'), /* actions: <Widget>[
          IconButton(
              onPressed: () async {
                _saveSettings;
              },
              icon: const Icon(Icons.save),
              tooltip: 'Save Settings')
        ] */
        ),
        body: SingleChildScrollView(
            child: Padding(
          padding: const EdgeInsets.fromLTRB(8, 8, 8, 8),
          child: Column(
            children: [
              Column(
                // Account
                children: [
                  const Padding(
                      padding: EdgeInsets.fromLTRB(0, 12, 0, 0),
                      child: Text('Account Information',
                          style: TextStyle(
                            fontSize: 17.0,
                          ))),
                  Padding(
                    padding: const EdgeInsets.fromLTRB(12, 0, 12, 12),
                    child: TextField(
                      controller: _usernameController,
                      inputFormatters: [LengthLimitingTextInputFormatter(25)],
                      decoration: InputDecoration(
                        hintText: 'Username',
                        labelText: 'Username',
                        border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(10.0)),
                      ),
                    ),
                  ),
                ],
              ),
              Container(
                child: Column(
                  // App Settings
                  children: [
                    // SwitchListTile(value: DarkMode, onChanged: Light => Dark => Light)
                    // ChangeThemeButtonWidget(),
                    TextButton(
                      onPressed: _saveSettings,
                      child: const Text('Save Settings'),
                    )
                  ],
                ),
              ),
            ],
          ),
        )));
  }

  void _saveSettings() {
    final newSettings = SettingsModal(
      username: _usernameController.text,
    );

    print(newSettings);
    print(_usernameController.text);
    _preferencesService.saveSettings(newSettings);
  }
}

shared_preferences.dart

import 'package:bit/main.dart';
import 'package:bit/saved_data.dart';
import 'package:shared_preferences/shared_preferences.dart';

class PreferencesService {
  Future saveSettings(SettingsModal settings) async {
    final preferences = await SharedPreferences.getInstance();

    await preferences.setString('username', settings.username);

    print('Saved Settings');
  }

  Future<SettingsModal> getSettings() async {
    final preferences = await SharedPreferences.getInstance();

    final username = preferences.getString('username')!;

    return SettingsModal(
      username: username,
    );
  }
}

saved_data.dart

import 'package:shared_preferences/shared_preferences.dart';
import 'package:bit/main.dart';

class SettingsModal {
  final String username;

  SettingsModal({
    required this.username,
  });
}

CodePudding user response:

The issue is coming because, you like to use user witch is not an constant. While adding const on Stack's children as Constance, which can be happened in this case, remove const and it won't show any errors.

child: Stack(
  children: [
    Align(
        alignment: Alignment.centerLeft,
        child: CircleAvatar(
          backgroundColor: Colors.white,
          radius: 50.0,
        )),
    Align(
        alignment: Alignment.centerRight,
        child: Text(
          user, 
          style: TextStyle(
            color: Colors.white,
            fontSize: 20.0,
          ),
        )),
  ],
),

To receive data from future(SharedPreference) we need to wait. You can use FutureBuilder in this case.

We can provide default value instead of using ! and make it static .

 static Future<SettingsModal> getSettings() async {
    final preferences = await SharedPreferences.getInstance();

    final username = preferences.getString('username') ?? "Not found";

    return SettingsModal(
      username: username,
    );
  }

Use PreferencesService.getSettings(), to get data.

Align(
    alignment: Alignment.centerRight,
    child: FutureBuilder<SettingsModal>(
      future: PreferencesService.getSettings(),
      builder: (context, snapshot) {
        if (snapshot.hasData &&
            snapshot.connectionState ==
                ConnectionState.done) {
          return Text(
            snapshot.data!.username,
            style: TextStyle(
              color: Colors.white,
              fontSize: 20.0,
            ),
          );
        }

        /// better to handle other cases, included on answer
        return CircularProgressIndicator();
      },
    )),

More about FutureBuilder

  • Related