'Set and Get String using Shared Preferences

I have two TextFields and two buttons, when I click the save button an alert dialog shows up and asks to save the information, I want to do the setString once I have clicked "Yes" but I can't figure out how.

I tried to work my way around with Controller.text but couldn't find a way to do it

Here is my code.

class _HomeState extends State<Home> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: cuerpo(context),
    );}}

Widget cuerpo(BuildContext context) {
  return Container(
    decoration: BoxDecoration(
        image: DecorationImage(
            image: NetworkImage(
                "https://i.ytimg.com/vi/J3dGdhUYVuQ/maxresdefault.jpg"),
            fit: BoxFit.cover)),
    child: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          nombre(),
          campo("User", isPassword: false),
          campo("Password", isPassword: true),
          boton(context, "Save", _showAlert),
          boton(context, "Enter", _navigatorButton),
        ],),),);}

Widget campo(String text, {bool isPassword = false}) {
  return Container(
    padding: EdgeInsets.symmetric(horizontal: 15.0, vertical: 5.0),
    child: TextField(
      obscureText: isPassword,
      decoration: InputDecoration(
        hintText: text,
        fillColor: Colors.white60,
        filled: true,
      ),),);}

Widget boton(BuildContext context, String texto, Function onPressed) {
  return ElevatedButton(
      style: ElevatedButton.styleFrom(
          primary: Colors.white,
          padding: EdgeInsets.symmetric(horizontal: 30, vertical: 5)),
      onPressed: () {
        onPressed(context);
      },
      child: Text(
        texto,
        style: TextStyle(color: Colors.black),
      ));}

void _showAlert(BuildContext context) {
  showDialog(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) => AlertDialog(
            title: Text("Alert"),
            content: Text("Data is correct?"),
            actions: [
              TextButton(
                  onPressed: () {
                    Navigator.pop(context);
                  },
                  child: Text("No")),
              TextButton(
                  onPressed: () {
                    Navigator.pop(context);
                  },
                  child: Text("Yes"))
            ],
          ));}


Solution 1:[1]

You need to use TextEditingController and fetch values from SharedPreferences in initState().

class _HomeState extends State<Home> {
  final _userController = TextEditingController();
  final _passwordController = TextEditingController();
  final String _keyUsername = "user";
  final String _keyPassword = "password";

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _fetchData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: cuerpo(context),
    );
  }

  Widget cuerpo(BuildContext context) {
    return Container(
      decoration: const BoxDecoration(
          image: DecorationImage(
              image: NetworkImage(
                  "https://i.ytimg.com/vi/J3dGdhUYVuQ/maxresdefault.jpg"),
              fit: BoxFit.cover)),
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            campo("User", _userController, isPassword: false),
            campo("Password", _passwordController, isPassword: true),
            boton(context, "Save", _showAlert),
          ],
        ),
      ),
    );
  }

  Widget campo(String text, TextEditingController controller,
      {bool isPassword = false}) {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: 15.0, vertical: 5.0),
      child: TextField(
        controller: controller,
        obscureText: isPassword,
        decoration: InputDecoration(
          hintText: text,
          fillColor: Colors.white60,
          filled: true,
        ),
      ),
    );
  }

  Widget boton(BuildContext context, String texto, Function onPressed) {
    return ElevatedButton(
        style: ElevatedButton.styleFrom(
            primary: Colors.white,
            padding: EdgeInsets.symmetric(horizontal: 30, vertical: 5)),
        onPressed: () {
          onPressed(context);
        },
        child: Text(
          texto,
          style: TextStyle(color: Colors.black),
        ));
  }

  void _showAlert(BuildContext context) {
    showDialog(
        context: context,
        barrierDismissible: false,
        builder: (BuildContext context) => AlertDialog(
              title: Text("Alert"),
              content: Text("Data is correct?"),
              actions: [
                TextButton(
                    onPressed: () {
                      Navigator.pop(context);
                      _saveData();
                    },
                    child: Text("No")),
                TextButton(
                    onPressed: () {
                      Navigator.pop(context);
                      FocusScope.of(context).requestFocus(FocusNode()); //will hide keyboard
                      _saveData();
                    },
                    child: Text("Yes"))
              ],
            ));
  }

  Future<void> _saveData() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setString(_keyUsername, _userController.text);
    await prefs.setString(_keyPassword, _passwordController.text);
  }

  Future<void> _fetchData() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    _userController.text = prefs.getString(_keyUsername,);
    _passwordController.text = prefs.getString(_keyPassword,);
    setState(() {

    });
  }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Smeet Bhatt