Flutter: jak wyświetlić następny indeks po wykonaniu określonej logiki w Swiper, gdzie GridView również ustawiony w Swiper?

Nov 25 2020

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

1 OussamaBelabbas Nov 25 2020 at 21:22

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.