Функция Flutter вызывается каждый раз, когда задано состояние

#flutter #flutter-state #flutter-hotreload

Вопрос:

Я создаю небольшую игру, в которой пользователю нужно угадать ответ, используя символы, отображаемые на экране в виде сетки, я создал представление сетки, содержащее символы из ответа и некоторые случайные символы, для генерации случайных символов я создал функцию randomString и вызывается внутри «Сборка виджета(контекст BuildContext)», но каждый раз, когда я нажимаю на кнопки моего представления сетки, вызываются функции randomString и меняются слова, поэтому я хочу, чтобы эти символы не менялись каждый раз.

Я тоже пробовал, но у меня это не работает.

 
import 'package:flutter/material.dart';

class PuzzlePage extends StatefulWidget {
  int? id;
  String? image1;
  String? image2;
  String? puzzleAnswer;

  PuzzlePage(this.id, this.image1, this.image2, this.puzzleAnswer);

  State<StatefulWidget> createState()
  {
    return _PuzzlePageState(this.id,this.image1,this.image2,this.puzzleAnswer);
  }


//State<StatefulWidget> createState() {
//  return _PuzzlePageState(this.id,this.image1,this.image2,this.puzzleAnswer);
}

class _PuzzlePageState extends State<PuzzlePage> {
  int? id;
  String? image1;
  String? image2;
  String? puzzleAnswer;

  _PuzzlePageState(this.id,this.image1,this.image2,this.puzzleAnswer);
  void initState(){
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    // deciding keyboard size
    int? remainingLetters=26-(puzzleAnswer!.length);
    int extraSize=(remainingLetters/2).ceil();
    print(extraSize);
    print(puzzleAnswer!.length);
    int keyboardSize=puzzleAnswer!.length extraSize;
    String randomCharactersString = RandomString(extraSize, puzzleAnswer!);
    String keyboardWords=randomCharactersString puzzleAnswer!;
    print(randomCharactersString);
    List selection=[];

// const answer= "cde";
    //final id = ModalRoute.of(context)!.settings.arguments as Id ;
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title:Text("Guess the answer"),
          centerTitle: true,
          automaticallyImplyLeading: true,
          leading: IconButton(icon:Icon(Icons.arrow_back),
            onPressed: () {
              Navigator.pop(context);
            },
          ),
        ),
        body: Container(

          color: Colors.white54,
          child: Column(
            children: [
              SizedBox(
                height: 60,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Container(
                      height: 125,
                      width: 125,
                      child: Image(image: AssetImage("assets/images/$image1"))),
                  SizedBox(
                    width: 20,
                  ),
                  Text("$randomCharactersString"),
                  Container(
                      height: 125,
                      width: 125,
                      child: Image(image: AssetImage("assets/images/$image2"))),
                ], ),
              Column(
                children: [
                  Container(
                      height: 250,
                      padding: EdgeInsets.all(10),
                      alignment: Alignment.center,
                      child: GridView.builder(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                        // childAspectRatio: 1,
                        crossAxisCount: 7,
                        crossAxisSpacing: 4,
                        mainAxisSpacing: 4,
                      ),
                          itemCount: puzzleAnswer!.length,
                          shrinkWrap: true,
                          itemBuilder: (context , index)
                          {
                            return ElevatedButton(

                              style: ElevatedButton.styleFrom(
                                primary: Colors.purple,
                                textStyle: TextStyle(
                                    fontSize: 20,
                                    fontWeight: FontWeight.bold
                                ),
                              ),
                              onPressed: null,
                              child: Text("d"),
                            );
                          }
                      )
                  ),
                ],
              ),
              Expanded(child:
              Container(
                  // height: 300,
                  padding: EdgeInsets.all(10),
                  alignment: Alignment.center,
                  child: GridView.builder(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    childAspectRatio: 1,
                    crossAxisCount: 7,
                    crossAxisSpacing: 4,
                    mainAxisSpacing: 4,
                  ),
                      itemCount: keyboardSize,
                      // shrinkWrap: true,
                      itemBuilder: (context , index)
                      {
                      String singleWord=keyboardWords[index];
                      int x=keyboardWords.length;
                      return InkWell(
                      onTap:(){
                      setState((){

                      if(selection.contains(keyboardWords[index]))
                      selection.remove(keyboardWords[index]);
                      else
                      selection.add(keyboardWords[index]);
                      });
                      },
                      child: Container(
                      padding:EdgeInsets.all(10),
                      alignment:Alignment.center,
                      decoration:BoxDecoration(
                      // color:selection.contains(keyboardWords[index])?Colors.blueAccent:Colors.grey,
                      borderRadius:BorderRadius.circular(7)
                      ),
                      child:Text(keyboardWords[index],
                      style:TextStyle(color:Colors.black)
                      ),
                      ),
                      );

                        // return ElevatedButton(
                        //   style: ElevatedButton.styleFrom(
                        //     primary: Colors.purple,
                        //     // padding: EdgeInsets.symmetric(horizontal: 50, vertical: 20),
                        //     textStyle: TextStyle(
                        //         fontSize: 20,
                        //         fontWeight: FontWeight.bold
                        //     ),
                        //   ),
                        //     onPressed: null,
                        //     child: Text("d"),
                        // );
                      }
                  )
              ),
              ),
            ],
          ),
        ),

      ),
    );
  }
}

 RandomString(int strlen,String puzzleAnswer){
  Random rnd = new Random();
  String result = "";
  const chars = "abcdefghijklmnopqrstuvwxyz";
  for (var i = 0; i < strlen; i  ) {
    // if (!puzzleAnswer.contains(chars[i])) {
      result  = chars[rnd.nextInt(chars.length)];
    // }
  }
  return resu<
}```
 

Комментарии:

1. Вы хотите загрузить его только один раз?

Ответ №1:

Сгенерируйте случайную строку из initState и поместите результат на уровень класса _PuzzlePageState :

 class _PuzzlePageState extends State<PuzzlePage> {
  ...
  late final String _randomCharactersString;

  _PuzzlePageState(this.id,this.image1,this.image2,this.puzzleAnswer);

  void initState(){
    super.initState();
    // deciding keyboard size
    int? remainingLetters=26-(puzzleAnswer!.length);
    int extraSize=(remainingLetters/2).ceil();
    print(extraSize);
    print(puzzleAnswer!.length);
    int keyboardSize=puzzleAnswer!.length extraSize;
    String randomCharactersString = RandomString(extraSize, puzzleAnswer!);
    ...
  }

  ...
}
 

Если вам нужно изменить случайную строку в каком-либо действии, создайте функцию для этого и вызывайте ее, когда вам нужно. Не забудьте позвонить setState() , чтобы сообщить об изменениях:

 class _PuzzlePageState extends State<PuzzlePage> {
  ...
  late String _randomCharactersString;

  _PuzzlePageState(this.id,this.image1,this.image2,this.puzzleAnswer);

  void initState(){
    super.initState();
    _generateRandomString();
  }

  ...

  void _someAction() {
    _generateRandomString();
    setState(() {});
  }

  void _generateRandomString() {
    // deciding keyboard size
    int? remainingLetters=26-(puzzleAnswer!.length);
    int extraSize=(remainingLetters/2).ceil();
    print(extraSize);
    print(puzzleAnswer!.length);
    int keyboardSize=puzzleAnswer!.length extraSize;
    String randomCharactersString = RandomString(extraSize, puzzleAnswer!);
    ...
  } 
}
 

Вероятно, вам потребуется добавить свойства уровня класса для keyboardWords и selection .