Nitneuq
Nitneuq

Reputation: 5012

how to save and load shared preference towards an other page in flutter

I tried to Save and share a variable Phone number string from a tabbar page to homepage. Currently my variable is display only after reload. I tried to display variable just after saved it.

my code :

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

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {

 @override
  Widget build(BuildContext context) {
  return new MaterialApp(
  title: 'Flutter Demo',
  theme: new ThemeData(
    primarySwatch: Colors.blue,
    ),
   );
 }
}
 class MyHomePage extends StatefulWidget {
 MyHomePage({Key key, this.title}) : super(key: key);

 final String title;

 @override
 _MyHomePageState createState() => new _MyHomePageState();
  }
  class _MyHomePageState extends State<MyHomePage> {

  String _variable;


 @override
  void initState() {
  super.initState();
   _loadvariable(); 
  }


  _loadvariable() async {   // load variable
    SharedPreferences prefs = await SharedPreferences.getInstance();
     setState(() {
     _variable = (prefs.getString('variable'));
     }
  );
 }

  @override
   Widget build(BuildContext context) {
    return new Scaffold(
    appBar: new AppBar(
    title: new Text(widget.title),
  ),
  bottomNavigationBar: BottomAppBar(
    color: Colors.blue,
    elevation: 20.0,
    child: ButtonBar(
      alignment: MainAxisAlignment.spaceBetween,
      children: <Widget>[
        IconButton(

          icon: Icon(Icons.phone),
          color: Colors.white,
          onPressed: () {
            Navigator.push(
              context,
              new MaterialPageRoute(builder: (context) => new Phone_Page()),
            );
          },
        ),
      ],
    ),
   ),

  body: new Center(
    child: new Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[

        new Text(
          '$_variable',
          style: Theme.of(context).textTheme.display1,
          ),
         ],
       ),
     ),
   );
  }
 }

here is my seconde page class, I can clic on the phone icon to show a dialog box, and I can write on the text field. After clic on save button my textfield is save, the dialog box is close and my variable is display on the card. But after return on the Homepage my variable isn't display. I need to reload the app to display it :(

class Phone_Page extends StatefulWidget {
 @override
Phone_PageState createState() => Phone_PageState();
 }
class Phone_PageState extends State<Phone_Page>   {

 final TextEditingController controller = new TextEditingController();
 String _variable;



 _loadvariable() async {     // load variable
  SharedPreferences prefs = await SharedPreferences.getInstance();
  setState(() {

   _variable = (prefs.getString('variable'))?? "";
  });
 }

 _savevariable() async {     // save variable 
  SharedPreferences prefs = await SharedPreferences.getInstance();
  setState(() {
  prefs.setString('variable', controller.text);
  });
 }

_deletevariable() async {   //delete variable 
  SharedPreferences prefs = await SharedPreferences.getInstance();
  setState(() {
  prefs.remove('variable');
 });
}


 @override
 void initState() {
 super.initState();
 _loadvariable()?? "";
 }

 @override
  Widget build(BuildContext context) {
   return new Scaffold(
    appBar: new AppBar(
      title: new Text("Phone"),
    ),
    body: new Center(
        child: new ListView(
            children: <Widget>[
              new Card(
                child: new Container(
                  padding: const EdgeInsets.all(20.0),
                  child: new Row(
                    children: [
                      new Expanded(
                        child: new Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [

                            new Text(
                              '$_variable',
                                 style: new TextStyle(
                                 color: Colors.grey[500],
                              ),
                            ),
                          ],
                        ),
                      ),
                            new IconButton(
                               icon: new Icon(Icons.add_call),
                               onPressed: ()
                            {
                            _showDialog();
                            }
                            ),

                      new IconButton(
                        icon: new Icon(Icons.delete),
                        onPressed: () { setState(() {
                          _deletevariable();
                          _savevariable();
                          _loadvariable();
                          }
                         );
                        },
                      ),
                    ],
                  ),
                ),
              ),
            ]
        )
    )
 );
}



_showDialog() async {
  await showDialog<String>(
  context: context,
  child: new AlertDialog(
    // contentPadding: const EdgeInsets.all(16.0),
    content: new Row(
      children: <Widget>[
        new Expanded(
          child: new TextField(
            controller: controller,
            autofocus: true,

            decoration: new InputDecoration(

                labelText: 'number', hintText: '06 - - - - - - - -'),
            // keyboardType: TextInputType.number,
          ),
        )
      ],
    ),

    actions: <Widget>[

      new FlatButton(
          child: const Text('save'),
          onPressed: (){
            setState(() { {
              _savevariable();

              Navigator.pop(context);
              }
             }
            );
          }
        )
       ],
     ),
   );
  }
}

Upvotes: 0

Views: 2541

Answers (1)

Arnold Parge
Arnold Parge

Reputation: 6867

To achieve what you want, you need to call _loadvariable() function of class MyHomePage from PhonePage class. To do that:

Refactor and remove _ from _loadvariable() and _MyHomePageState so that it won't be private anymore. Pass MyHomePageState class instance to PhonePage as follows:

Navigator.push(
    context,
    new MaterialPageRoute(builder: (context) => new PhonePage(
    myHomePageState: this,
    )),
);

Call loadvariable() in _savevariable() like

_savevariable() async {
// save variable
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
    prefs.setString('variable', controller.text);
});
widget.myHomePageState.loadvariable();
}

Make sure the myHomePageState type is var so that you won't get type error:

class PhonePage extends StatefulWidget {
    var myHomePageState;
    PhonePage({this.myHomePageState});
    @override
    PhonPageState createState() => PhonPageState();
}

Upvotes: 2

Related Questions