Home > other >  Can't figure it out how to use SharedPreferences in flutter, please help :)
Can't figure it out how to use SharedPreferences in flutter, please help :)

Time:09-02

I am trying to make in my app a stars counter and when the app is closed and reopened, the number of stars should remain the same, not going from 0 again. All I've done is this, but it doesn't work.

int correctGuesses = 0;

  String language1 = "";
  String language2 = "";
  String language3 = "";

  Widget buildGame() {

    final myController = TextEditingController();

    @override
    void dispose() {
      myController.dispose();
      super.dispose();
    }

    int nextNumber({required int min, required int max}) =>
        min   Random().nextInt(max - min   1);

    int rowNumber = Random().nextInt(1);
    int columnNumber = nextNumber(min: 1, max: 10);
    final language = languageMatrix[rowNumber][0];
    final sentence = languageMatrix[rowNumber][columnNumber];

    return SingleChildScrollView(
      child: Column(
        children: <Widget> [
          Image.asset('assets/GameLogo_2.png'),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 0),
            child: Container(
              decoration: BoxDecoration(
                color: Colors.teal[200],
                borderRadius: const BorderRadius.all(Radius.circular(10)),
                border: Border.all(color: Colors.black)
              ),
              height: 125,
              child: Center(
                  child: Text(
                    sentence,
                    style: const  TextStyle(fontSize: 17),
                    textAlign: TextAlign.center,
                  )
              ),
            ),
          ),
          Container(height: 20),
          Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget> [
                 Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
                  child: SizedBox(
                    width: 200,
                    //height: 70,
                    child: TextField(
                      cursorColor: Colors.teal,
                      controller: myController,
                      decoration: const InputDecoration(
                        border: OutlineInputBorder(),
                        hintText: 'Enter a language',
                      ),
                    ),
                  )
                ),
                TextButton(
                  style: TextButton.styleFrom(
                      textStyle: const TextStyle(fontSize: 20)),
                  onPressed: () {
                    _incrementCounter();
                    if (counter >= 1 && counter <= 3 )
                        {
                          if (myController.text == language)
                          {
                            if (counter == 1)
                            {
                              language1 = language;
                              firstAttempt = myController.text;
                              correctGuesses  ;
                            }
                            if (counter == 2)
                            {
                              language2 = language;
                              secondAttempt = myController.text;
                              correctGuesses  ;
                            }
                            if (counter == 3)
                            {
                              language3 = language;
                              thirdAttempt = myController.text;
                              correctGuesses  ;
                            }
                          }
                          else
                          {
                            if (counter == 1)
                            {
                              language1 = language;
                              firstAttempt = myController.text;
                            }
                            if (counter == 2)
                            {
                              language2 = language;
                              secondAttempt = myController.text;
                            }
                            if (counter == 3)
                            {
                              language3 = language;
                              thirdAttempt = myController.text;
                            }
                          }
                        }
                    if (counter == 3)
                    {
                      if (correctGuesses == 0)
                        {
                          showDialog<String>(
                              barrierDismissible: false,
                              context: context,
                              builder: (BuildContext context) => AlertDialog(
                                title: const Text('Your Score', textAlign: TextAlign.center, style: TextStyle(fontSize: 25),),
                                content: SizedBox(
                                    height: 250,
                                    child: Column(
                                        children: <Widget>[
                                          Row(
                                            mainAxisAlignment: MainAxisAlignment.center,
                                            children: const <Widget>[
                                              Icon(Icons.star_border, size: 70, color: Colors.teal),
                                              Icon(Icons.star_border, size: 70, color: Colors.teal),
                                              Icon(Icons.star_border, size: 70, color: Colors.teal),
                                            ],
                                          ),
                                          Container(height: 15),
                                          Text('Sentence 1: $language1', textAlign: TextAlign.center),
                                          Container(height: 15),
                                          Text('Sentence 2: $language2', textAlign: TextAlign.center),
                                          Container(height: 15),
                                          Text('Sentence 3: $language3', textAlign: TextAlign.center),
                                          Container(height: 15),
                                          const Text('Check your profile to see your total number of stars, or go back home and start a new round!', textAlign: TextAlign.center,)
                                        ]
                                    )
                                ),
                                elevation: 24,
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(10),
                                ),
                                actionsAlignment: MainAxisAlignment.spaceAround,
                                actions: <Widget>[
                                  TextButton(
                                    onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (context) => StartPage())),
                                    child: const Text('Home'),
                                  ),
                                  TextButton(
                                    onPressed: () {
                                      Navigator.push(context, MaterialPageRoute(builder: (context) => ProfilePage()));
                                    },
                                    child: const Text('Profile'),
                                  ),
                                ],
                              )
                          );
                        }
                      if (correctGuesses == 1)
                        {
                          showDialog<String>(
                              barrierDismissible: false,
                              context: context,
                              builder: (BuildContext context) => AlertDialog(
                                title: const Text('Your Score', textAlign: TextAlign.center, style: TextStyle(fontSize: 25),),
                                content: SizedBox(
                                    height: 250,
                                    child: Column(
                                        children: <Widget>[
                                          Row(
                                            mainAxisAlignment: MainAxisAlignment.center,
                                            children: const <Widget>[
                                              Icon(Icons.star, size: 70, color: Colors.teal),
                                              Icon(Icons.star_border, size: 70, color: Colors.teal),
                                              Icon(Icons.star_border, size: 70, color: Colors.teal),
                                            ],
                                          ),
                                          Container(height: 15),
                                          Text('Sentence 1: $language1', textAlign: TextAlign.center),
                                          Container(height: 15),
                                          Text('Sentence 2: $language2', textAlign: TextAlign.center),
                                          Container(height: 15),
                                          Text('Sentence 3: $language3', textAlign: TextAlign.center),
                                          Container(height: 15),
                                          const Text('Check your profile to see your total number of stars, or go back home and start a new round!', textAlign: TextAlign.center,)
                                        ]
                                    )
                                ),
                                elevation: 24,
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(10),
                                ),
                                actionsAlignment: MainAxisAlignment.spaceAround,
                                actions: <Widget>[
                                  TextButton(
                                    onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (context) => StartPage())),
                                    child: const Text('Home'),
                                  ),
                                  TextButton(
                                    onPressed: () {
                                      //setStarsNumber(correctGuesses);
                                      Navigator.push(context, MaterialPageRoute(builder: (context) => ProfilePage()));
                                    },
                                    child: const Text('Profile'),
                                  ),
                                ],
                              )
                          );
                        }
                      if (correctGuesses == 2)
                        {
                          showDialog<String>(
                              barrierDismissible: false,
                              context: context,
                              builder: (BuildContext context) => AlertDialog(
                                title: const Text('Your Score', textAlign: TextAlign.center, style: TextStyle(fontSize: 25),),
                                content: SizedBox(
                                    height: 250,
                                    child: Column(
                                        children: <Widget>[
                                          Row(
                                            mainAxisAlignment: MainAxisAlignment.center,
                                            children: const <Widget>[
                                              Icon(Icons.star, size: 70, color: Colors.teal),
                                              Icon(Icons.star, size: 70, color: Colors.teal),
                                              Icon(Icons.star_border, size: 70, color: Colors.teal),
                                            ],
                                          ),
                                          Container(height: 15),
                                          Text('Sentence 1: $language1', textAlign: TextAlign.center),
                                          Container(height: 15),
                                          Text('Sentence 2: $language2', textAlign: TextAlign.center),
                                          Container(height: 15),
                                          Text('Sentence 3: $language3', textAlign: TextAlign.center),
                                          Container(height: 15),
                                          const Text('Check your profile to see your total number of stars, or go back home and start a new round!', textAlign: TextAlign.center,)
                                        ]
                                    )
                                ),
                                elevation: 24,
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(10),
                                ),
                                actionsAlignment: MainAxisAlignment.spaceAround,
                                actions: <Widget>[
                                  TextButton(
                                    onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (context) => StartPage())),
                                    child: const Text('Home'),
                                  ),
                                  TextButton(
                                    onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (context) => ProfilePage())),
                                    child: const Text('Profile'),
                                  ),
                                ],
                              )
                          );
                        }
                    if (correctGuesses == 3)
                      {
                        showDialog<String>(
                            barrierDismissible: false,
                            context: context,
                            builder: (BuildContext context) => AlertDialog(
                              title: const Text('Your Score', textAlign: TextAlign.center, style: TextStyle(fontSize: 25),),
                              content: SizedBox(
                                  height: 250,
                                  child: Column(
                                      children: <Widget>[
                                        Row(
                                          mainAxisAlignment: MainAxisAlignment.center,
                                          children: const <Widget>[
                                            Icon(Icons.star, size: 70, color: Colors.teal),
                                            Icon(Icons.star, size: 70, color: Colors.teal),
                                            Icon(Icons.star, size: 70, color: Colors.teal),
                                          ],
                                        ),
                                        Container(height: 15),
                                        Text('Sentence 1: $language1', textAlign: TextAlign.center),
                                        Container(height: 15),
                                        Text('Sentence 2: $language2', textAlign: TextAlign.center),
                                        Container(height: 15),
                                        Text('Sentence 3: $language3', textAlign: TextAlign.center),
                                        Container(height: 15),
                                        const Text('Check your profile to see your total number of stars, or go back home and start a new round!', textAlign: TextAlign.center,)
                                      ]
                                  )
                              ),
                              elevation: 24,
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(10),
                              ),
                              actionsAlignment: MainAxisAlignment.spaceAround,
                              actions: <Widget>[
                                TextButton(
                                  onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (context) => StartPage())),
                                  child: const Text('Home'),
                                ),
                                TextButton(
                                  onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (context) => ProfilePage())),
                                  child: const Text('Profile'),
                                ),
                              ],
                            )
                        );
                      }
                    }
                    myController.clear();
                  },
                  child: const Text('Guess'),
                )
              ]
            ),
          Container(height: 20),
          Padding(
              padding: const EdgeInsets.symmetric(horizontal: 100, vertical: 5),
              child: Container(
                height: 30,
                decoration: BoxDecoration(
                  color: Colors.teal[200],
                  borderRadius: const BorderRadius.all(Radius.circular(10)),
                border: Border.all(color: Colors.black),
                ),
                child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget> [
                      const Text('Sentence 1/3: '),
                      Text(firstAttempt)
                    ]
                )
              )
          ),
          Padding(
              padding: const EdgeInsets.symmetric(horizontal: 100, vertical: 5),
              child: Container(
                  height: 30,
                  decoration: BoxDecoration(
                    color: Colors.teal[200],
                    borderRadius: const BorderRadius.all(Radius.circular(10)),
                    border: Border.all(color: Colors.black),
                  ),
                  child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget> [
                        const Text('Sentence 2/3: '),
                        Text(secondAttempt)
                      ]
                  )
              )
          ),
          Padding(
              padding: const EdgeInsets.symmetric(horizontal: 100, vertical: 5),
              child: Container(
                  height: 30,
                  decoration: BoxDecoration(
                    color: Colors.teal[200],
                    borderRadius: const BorderRadius.all(Radius.circular(10)),
                    border: Border.all(color: Colors.black),
                  ),
                  child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget> [
                        const Text('Sentence 3/3: '),
                        Text(thirdAttempt)
                      ]
                  )
              )
          ),
          Container(
            height: 10,
          ),
        ]
      ),
    );
  }


  Future<int> getOldStarsNumber() async {
    final SharedPreferences pref = await SharedPreferences.getInstance();
    int oldStarsNumber = (pref.getInt('keyStarsNumber') ?? 0);
    return oldStarsNumber;
  }

  Future<void> updateStarsNumber() async{
    final SharedPreferences pref = await SharedPreferences.getInstance();
    int oldStarsNumber = await getOldStarsNumber();
    int starsNumber = correctGuesses   oldStarsNumber;
    pref.setInt('keyStarsNumber', 0);
  }


This is from the first class I am using, and this is where I calculate the number of stars.

class ProfilePageState extends State<ProfilePage> {

  int? starsNumber;

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

  Future<void> setStarsNumber() async {
    final SharedPreferences pref = await SharedPreferences.getInstance();
    starsNumber = pref.getInt('keyStarsNumber');
    setState(() {

    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('My profile, coming soon'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Icon(Icons.star, size: 200, color: Colors.teal,),
            Text('$starsNumber', style: const TextStyle(fontSize: 100)),
          ],
        ),
      ),
    );
  }
}

And this is the second class, where i get that number of stars and putting it in a Text. With this code, the total number of stars always remain 0, and I dont know what to do, so please help. The correctGuesses variable is from the widget Build above, which does work...all i am thinking is that maybe is that correctGuesses variable losses its value. I think im 100% wrong..but thats what i am thinking. Please help me, im stuck :) Thank you very much!

CodePudding user response:

I think the problem with your code is that you're initializing the instance of shared preferences over and over again with each update in your updateStarsNumber function. Try to have an app-wide instance of shared preferences. You can initialize it in your main function, call it prefs, and inject it wherever it's needed.

Basically, only call await SharedPreferences.getInstance(); once in the app.

  • Related