Flutter: como mostrar o próximo índice após completar uma lógica específica no Swiper, onde GridView também é definido no Swiper?
Estou tentando fazer um jogo de palavras. Em primeiro lugar, o índice será branco. se o usuário clicar na resposta correta, o índice ficará com a cor verde e irá para a próxima tela, e também o índice será branco na próxima tela .. novamente se o usuário clicar na resposta incorreta, o índice ficará com a cor vermelha e não deixe ir para o próxima página até que o usuário coloque a resposta correta ...
defini um GridView no Swiper (o Swiper levou importando, import 'package: flutter_swiper / flutter_swiper.dart';). e quero mostrar o próximo índice do Swiper depois de concluir uma lógica no GridView. suponha que eu tenha uma longa lista de strings (array) e peguei quatro strings de valores dessa lista (array) aleatoriamente, esta string de quatro valores definida no índice GridView.
Novamente eu faço uma nova lista de strings (array) por esta string de quatro valores e peguei um valor desta nova lista de strings (array) aleatoriamente, esta string única definida no Swiper. finalmente, se o usuário puder selecionar o valor do índice Swiper para o valor do índice GridView quatro corretamente, o usuário poderá ver a próxima tela no Swiper. mas a saída não está funcionando corretamente. O problema é - no início eu defino a cor branca no índice GridView, se estiver correto, a resposta deve ser a cor verde no índice GridView e a incorreta será a cor vermelha no índice GridView. aqui está a minha lógica que tornou tudo confuso.
import 'package:flutter_swiper/flutter_swiper.dart';
import 'dart:math';
class GameWordRoute extends StatefulWidget {
@override
_GameWordRouteState createState() => _GameWordRouteState(); }
class _GameWordRouteState extends State<GameWordRoute> {
SwiperController _controller = SwiperController();
SwiperControl _control = SwiperControl(color: Colors.white);
double get _width => MediaQuery.of(context).size.width;
double get _height => MediaQuery.of(context).size.height;
bool inLastPage = true;
bool _answer = false;
List<Color> colorList = <Color>[Colors.white, Colors.white, Colors.white, Colors.white,];
List<String> gameButtonList = <String>[];
FlutterTts flutterTts = FlutterTts();
@override
Widget build(BuildContext context) {
var sizeDevice = MediaQuery.of(context).size;
final orientation = MediaQuery.of(context).orientation;
final double itemHeight = sizeDevice.width / 6;
final double itemWidth = sizeDevice.width / 2;
return Scaffold(
backgroundColor: Colors.purple, // white
body: SafeArea(
child: Column(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
color: Colors.lightBlueAccent,
)),
Expanded(
flex: 8,
child: Container(
color: Colors.cyan,
child: Swiper(
controller: _controller,
loop: false,
scrollDirection: Axis.horizontal,
itemCount: word_data.drink.length,
onIndexChanged: (value) {
if (value == word_data.drink.length - 1)
setState(() {
inLastPage = true;
});
else {
setState(() {
inLastPage = true; // false
});
}
},
itemBuilder: (BuildContext context, int index) {
gameButtonList.clear();
var fourValueRandom = new Random();
for (var i = 0; i < 4; i++) {
final fourGameBtnRandom = word_data.drink[fourValueRandom.nextInt(word_data.drink.length)];
gameButtonList.add(fourGameBtnRandom);
}
var oneValueRandom = new Random();
var oneValueRandomGet = gameButtonList[oneValueRandom.nextInt(gameButtonList.length)];
var wordDataReplace = oneValueRandomGet.replaceAll(" ", "_").toLowerCase();
return Container(
child: Column(
children: <Widget>[
Expanded(
flex: 8,
child: Container(
color: Colors.purple,
width: _width,
alignment: Alignment.center,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Image.asset("asset/drink_images/" + wordDataReplace + ".png",
fit: BoxFit.contain,
),
),
)),
Expanded(
flex: 1,
child: Container(
color: Colors.yellow,
width: _width,
alignment: Alignment.center,
// "${categoryTitleArray[index]}" child: Text("What is this?"), )), Expanded( flex: 4, child: Container( color: Colors.yellow[200], width: _width, alignment: Alignment.center, child: GridView.builder( padding: EdgeInsets.all(8), itemCount: 4, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: (orientation == Orientation.portrait) ? 2 : 4, crossAxisSpacing: 5, mainAxisSpacing: 5, childAspectRatio: (itemWidth / itemHeight), ), itemBuilder: (BuildContext context, int index) { return GestureDetector( onTap: () { if (index == 0) { if (gameButtonList[0] == oneValueRandomGet){ _answer = true; inLastPage = false; colorList[0] = Colors.green; setState((){}); _showCorrectAndIncorrectDialog("Congratulation", "asset/icon_images/ok_emoji.png", "Correct answer", Colors.green); }else{ colorList[0] = Colors.red; inLastPage = true; setState((){}); } } else if (index == 1) { if (gameButtonList[1] == oneValueRandomGet){ _answer = true; colorList[1] = Colors.green; setState((){}); _showCorrectAndIncorrectDialog("Congratulation", "asset/icon_images/ok_emoji.png", "Correct answer", Colors.green); inLastPage = false; }else{ colorList[1] = Colors.red; inLastPage = true; setState((){}); } } else if (index == 2) { if (gameButtonList[2] == oneValueRandomGet){ _answer = true; colorList[2] = Colors.green; setState((){}); _showCorrectAndIncorrectDialog("Congratulation", "asset/icon_images/ok_emoji.png", "Correct answer", Colors.green); inLastPage = false; }else{ colorList[2] = Colors.red; inLastPage = true; setState((){}); } } else if (index == 3) { if (gameButtonList[3] == oneValueRandomGet){ _answer = true; colorList[3] = Colors.green; inLastPage = false; setState((){}); _showCorrectAndIncorrectDialog("Congratulation", "asset/icon_images/ok_emoji.png", "Correct answer", Colors.green); }else{ colorList[3] = Colors.red; inLastPage = true; setState((){}); } } }, child: Container( child: new Card( elevation: 0, color: colorList[index], //Colors.transparent, child: Center( child: Text( "${gameButtonList[index]}",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.black),
),
),
),
),
);
}),
)),
],
),
);
},
),
),
),
Expanded(
flex: 1,
child: Container(
color: Colors.lightBlueAccent,
)),
],
),
),
);
}
void _showCorrectAndIncorrectDialog(String _title, String _image, String _subTitle, Color _color){
showDialog(
context: context,
builder: (BuildContext context){
Future.delayed(Duration(milliseconds: 500), () {
Navigator.of(context).pop(true);
});
return AlertDialog(
title: Text(_title, textAlign: TextAlign.center, style: TextStyle(color: _color),),
content: Container(
height: _width/1.1,
child: Column(
children: <Widget>[
Expanded(
flex: 4,
child: Container(
// color: Colors.cyan[100],
child: Image.asset(_image,
fit: BoxFit.cover,
),
),
),
SizedBox(height: 8),
Expanded(
flex: 1,
child: Container(
color: Colors.cyan,
child: Center(
child: Text(
_subTitle,
style: TextStyle(
// fontSize: 24,
),
),
),
),
),
],
),
),
);
}
);
}
}
Respostas
então a primeira coisa que você deve fazer é mudar a sua função onTap no seu detector de gestos para um código mais simples Você não deve verificar cada número para o índice porque o índice já é aquele número
Para ser mais claro quando você chama list [index], o índice aqui é um número inteiro, então se index == 1 você está chamando lista [1] e se index == 5 você está chamando lista [5], você não t tenho que testar se índice == 1 ou algo parecido
então seu código deve ser algo assim
onTap: () async{
if (gameButtonList[index] == oneValueRandomGet){
_answer = true;
colorList[index] = Colors.green;
inLastPage = false;
setState((){});
_showCorrectAndIncorrectDialog("Congratulation", "asset/icon_images/ok_emoji.png", "Correct answer", Colors.green);
}else{
colorList[index] = Colors.red;
inLastPage = true;
setState((){});
}
},
E a seguir o problema de testar se a resposta está correta ou não e mudar a cor e ir para a próxima tela
A primeira coisa por favor mova essas linhas em sua função de construtor de item para uma função que você pode chamar de qualquer lugar como este, por exemplo
void newQuestion(){
gameButtonList.clear();
var fourValueRandom = new Random();
for (var i = 0; i < 4; i++) {
final fourGameBtnRandom = word_data.drink[fourValueRandom.nextInt(word_data.drink.length)];
gameButtonList.add(fourGameBtnRandom);
}
oneValueRandomGet = gameButtonList[fourValueRandom.nextInt(gameButtonList.length)];
wordDataReplace = oneValueRandomGet.replaceAll(" ", "_").toLowerCase();
}
e você pode fazer esta pergunta depois de chamar seu dialogAlert se alterar a linha ao chamar _showCorrectAndIncorrectDialog (...) para
_showCorrectAndIncorrectDialog("Congratulation", "asset/icon_images/ok_emoji.png", "Correct answer", Colors.green);
newQuestion() //**Add this line also**
Notas :
- Lembre-se de declarar as variáveis de que você precisa em sua classe para que sejam alteradas na função newQuestion
- Na primeira vez que você iniciar o aplicativo, as variáveis como "oneValueRandomGet" serão nulas, então você não pode mostrar nenhum dado, chame oneQuestion () em seu initState para que, ao iniciar o aplicativo, você tenha sua primeira pergunta pronta diretamente.
Espero que tudo isso não o confunda. Tentei o meu melhor para simplificar e dar-lhe a edição e a resposta mais simples possíveis, por favor, se você ainda não conseguiu resolver o seu problema, eu realmente aconselharia você a tentar reescrever seu código e tentar torná-lo o mais simples possível.
Obrigado.