#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
.