Flutter: jak wyświetlić następny indeks po wykonaniu określonej logiki w Swiper, gdzie GridView również ustawiony w Swiper?
Próbuję stworzyć grę słowną. Przede wszystkim indeks będzie biały. jeśli użytkownik kliknie poprawną odpowiedź, indeks zmieni kolor na zielony i przejdzie do następnego ekranu, również indeks będzie biały na następnym ekranie .. ponownie, jeśli użytkownik kliknie nieprawidłową odpowiedź, to indeks będzie miał kolor czerwony i nie puszczaj następna strona, aż użytkownik umieści poprawną odpowiedź ...
Ustawiłem GridView w Swiper (Swiper wziął przez import, import 'package: flutter_swiper / flutter_swiper.dart';). i chcę pokazać następny indeks Swipera po wykonaniu logiki w GridView. załóżmy, że mam długą listę ciągów (tablicę) i wziąłem ciąg czterech wartości z tej listy (tablicy) losowo, ten ciąg czterech wartości jest ustawiony w indeksie GridView.
Ponownie tworzę nową listę ciągów (tablicę) na podstawie tego ciągu czterech wartości i wziąłem wartość z tej nowej listy ciągów (tablicy) losowo, ten pojedynczy ciąg ustawiony w Swiper. na koniec, jeśli użytkownik może poprawnie wybrać wartość indeksu Swiper do wartości indeksu GridView cztery, wówczas użytkownik może zobaczyć następny ekran w Swiper. ale wyjście nie działa prawidłowo. Problem w tym, że na początku ustawiłem kolor biały w indeksie GridView, jeśli poprawna odpowiedź powinna być koloru zielonego w indeksie GridView, a niepoprawna będzie kolor czerwony w indeksie GridView. oto moja logika, która sprawiła, że było bałagan.
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,
),
),
),
),
),
],
),
),
);
}
);
}
}
Odpowiedzi
więc pierwszą rzeczą jaką powinieneś zrobić to zmienić swoją funkcję onTap w twoim detektorze gestów na prostszy kod Nie powinieneś weryfikować każdej liczby dla indeksu ponieważ indeks jest już tą liczbą
Aby było jaśniej, kiedy dzwonisz do listy [index], indeks tutaj jest liczbą całkowitą, więc jeśli indeks == 1 dzwonisz do listy [1], a jeśli indeks == 5, dzwonisz do listy [5] nie Nie muszę sprawdzać, czy index == 1 czy coś takiego
więc twój kod powinien wyglądać mniej więcej tak
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((){});
}
},
A następnie problem z testowaniem, czy odpowiedź jest poprawna, czy nie, i zmiana koloru i przejście do następnego ekranu
Po pierwsze, przenieś te wiersze w swojej funkcji tworzenia przedmiotów do funkcji, którą możesz wywołać z dowolnego miejsca, na przykład
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();
}
i możesz wywołać to pytanie po wywołaniu okna dialogAlert, jeśli zmienisz linię podczas wywoływania funkcji _showCorrectAndIncorrectDialog (...) na
_showCorrectAndIncorrectDialog("Congratulation", "asset/icon_images/ok_emoji.png", "Correct answer", Colors.green);
newQuestion() //**Add this line also**
Uwagi:
-Pamiętaj o zadeklarowaniu zmiennych, których potrzebujesz w swojej klasie, aby zostały zmienione w funkcji newQuestion
- Przy pierwszym uruchomieniu aplikacji zmienne, takie jak „oneValueRandomGet”, będą miały wartość null, więc nie możesz wyświetlić żadnych danych, wywołaj oneQuestion () w swoim initState, aby podczas uruchamiania aplikacji było gotowe bezpośrednio pierwsze pytanie.
Mam nadzieję, że to wszystko Cię nie zmyli. Zrobiłem wszystko, co w mojej mocy, aby uprościć i dać Ci najprostszą możliwą edycję i odpowiedź, proszę, jeśli nadal nie jesteś w stanie rozwiązać swojego problemu, naprawdę doradziłbym, aby spróbować przepisać kod i spróbować uczyń to tak prostym, jak to tylko możliwe.
Dziękuję Ci.