简体   繁体   English

无法弄清楚如何在 flutter 中使用 SharedPreferences,请帮助:)

[英]Can't figure it out how to use SharedPreferences in flutter, please help :)

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.我试图在我的应用程序中制作一个星星计数器,当应用程序关闭并重新打开时,星星的数量应该保持不变,而不是再次从 0 开始。 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 的数据,这是我计算星数的地方。

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.这是第二个 class,我在其中获得了该数量的星星并将其放入文本中。 With this code, the total number of stars always remain 0, and I dont know what to do, so please help.有了这段代码,星星总数始终保持为0,我不知道该怎么办,所以请帮忙。 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. correctGuesses 变量来自上面的小部件 Build,它确实有效……我所想的是,这可能是 correctGuesses 变量失去了它的价值。 I think im 100% wrong..but thats what i am thinking.我认为我 100% 错了..但这就是我的想法。 Please help me, im stuck:) Thank you very much!请帮助我,我卡住了:)非常感谢!

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.我认为您的代码的问题在于,您在 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.您可以在主 function 中对其进行初始化,将其命名为 prefs,并在需要的地方注入它。

Basically, only call await SharedPreferences.getInstance();基本上,只调用 await SharedPreferences.getInstance(); once in the app.一次在应用程序中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM