How can I navigate in a quiz app maded by GridView.builder?

49 Views Asked by At

I have this models of a quiz app, and a want to make a different questions to different categories and I want to know how to navigate. (when I tap in a categories, I want to go to the questions of the categories selected).

This is my categories model:

class Selectclass {
  final String selectedclasse ;
  final String quizimage;
  final List<Question> questions;
  Selectclass (
 {required this.questions,
  required this.selectedclasse ,
 required this.quizimage,
});
} 
final List<Selectclass> quizclasses = [
    Selectclass(selectedclasse: "title", quizimage: "assets/virus.png" ,  questions: [], ),
    Selectclass(selectedclasse: "title1", quizimage: "assets/virus.png" , questions: []),
    Selectclass(selectedclasse: "title", quizimage: "assets/virus.png" , questions: []),
    Selectclass(selectedclasse: "title1", quizimage: "assets/virus.png" , questions: []),

Questions model:

class Question {
  final String text ;
  final String solution ;
  final List<Option> options ;
  bool isLocked  ;
  Option? selectedOption;

  Question( {
    required this.text ,
    required this.solution,
    required this.options,
    this.selectedOption,
    this.isLocked = false ,
  });
}

And the options

class Option {
  final String text ;
  final bool isCorrect ;
  Option({
    required this.isCorrect,
    required this.text,
  });
}

final questions = [
  Question(
    text: ".......... ?",
     solution: ".........", 
     options: [
      Option(isCorrect: false, text: "....."),
      Option(isCorrect: true, text: "......"),
      Option(isCorrect: false, text: "......"),
      Option(isCorrect: false, text: "......"),
     ]),
    Question(
    text: "what can we call a ....  ?",
     solution: "we can call it ;;;;;", 
     options: [
      Option(isCorrect: false, text: " A) real"),
      Option(isCorrect: false, text: "B) barca"),
      Option(isCorrect: true, text: "C) manchester"),
      Option(isCorrect: false, text: "D) psg"),
     ],),
   
];

My question is how I can add a question for each category and how can I navigate to them?

This is the questions page

class QuestionsPgae extends StatelessWidget {
  const QuestionsPgae({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body:QuestionsPageBody() ,
    );
  }
}

class QuestionsPageBody extends StatefulWidget {
  const QuestionsPageBody({super.key});

  @override
  State<QuestionsPageBody> createState() => _QuestionsPageBodyState();
}

class _QuestionsPageBodyState extends State<QuestionsPageBody> {
  late PageController _controller ;
  int _questionNumber = 1 ;
  int _score = 0 ;
  bool _isLocked = false ;
  @override
  void initState() {
    super.initState();
    _controller = PageController(initialPage: 0);
  }
  @override
  Widget build(BuildContext context) {
     
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 24),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children:[ 
          const CustomAppBar(title: ''),
          const SizedBox(height: 24,),
          Expanded(
            child: PageView.builder(
              controller: _controller,
              itemCount: questions.length,
              itemBuilder: (context, index) {
                final _question = questions[index];
                return buildQuestion(_question);
              },
              ),
          ),
          _isLocked ?buildElevatedButton() : const SizedBox.shrink(),
          const SizedBox(height: 20,),
          ]
      ),
    );
  }
  Column buildQuestion ( Question question) {
    return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('Question $_questionNumber/${questions.length}'
          , style: const TextStyle(color: Colors.yellow , fontSize: 28 , fontWeight: FontWeight.bold),
          ),
          const SizedBox(height: 24,),
          Text(question.text , style: const TextStyle(fontSize: 24),),
          const SizedBox(height: 24,),
          Expanded(
            child: OptionsWidget(question:question, onClickedOption: (option) {
              if (question.isLocked){
                return;
              }else {
                setState(() {
                question.isLocked = true ;
                question.selectedOption = option;
              });
              _isLocked = question.isLocked ;
              if ( question.selectedOption!.isCorrect){
                _score++;
              }
              }
              },)
            ),
            
        ],
    );
  }
  ElevatedButton  buildElevatedButton() {
    return ElevatedButton(
      onPressed: (){
        if(_questionNumber < questions.length){
          _controller.nextPage(
            duration : const Duration(microseconds: 250),
            curve: Curves.easeInExpo,
          );
          setState(() {
            _questionNumber++;
            _isLocked = false;
          });
        }else {
          Navigator.pushReplacement(
            context, MaterialPageRoute(
              builder: (context) => ResultPage(score:_score),));
        }
      }, 
      child: Text(_questionNumber < questions.length?'Suivante': 'Voir les résultats')
      );
  }
}

class OptionsWidget extends StatelessWidget {
  final Question question;
  final ValueChanged<Option> onClickedOption;
  const OptionsWidget({super.key, required this.question, required this.onClickedOption});

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Column(
        children: [Column(
          children: question.options.map((option) =>buildOption(context,option)).toList(),
          
        ),
        
        ]
      ),
    );
  }
  Widget buildOption (BuildContext context , Option option) {
    final color = getColorForOotion(option,question);
      return GestureDetector(
        onTap: () => onClickedOption(option),
        child: Container(
          decoration: BoxDecoration(
          color: Colors.white,
          boxShadow:  [
            BoxShadow(
              color: const Color(0xFF5A6CEA).withOpacity(0.08),
            ),
          ],
          border: Border.all( color: color ,),
          borderRadius: BorderRadius.circular(10),
          
        ),
          height: 50,
          padding: const EdgeInsets.all(12),
          margin: const EdgeInsets.only(bottom: 10),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Text(
                option.text,
                style: const TextStyle(fontSize: 20),
              ),
              getIconForOption(option, question),
              
            ],
          ),
        ),
      );
     
      
    }
    Color getColorForOotion(Option option , Question question) {
      final isSelected = option == question.selectedOption;
       if(question.isLocked) {
        if(isSelected){
          return option.isCorrect? Colors.green
          : Colors.red;
        } else if (option.isCorrect) { 
          return  Colors.green;
        }
      }
      return const Color(0xFFF4F6F9);
    }
    Widget getIconForOption (Option option , Question question) {
      final isSelected = option == question.selectedOption;
      if(question.isLocked) {
        if(isSelected){
          return option.isCorrect?const Icon(Icons.check_circle, color: Colors.green,)
          :const Icon(Icons.cancel , color: Colors.red,);
        } else if (option.isCorrect) { 
          return const Icon(Icons.check_circle , color: Colors.green,);
        }
      }
      return const SizedBox.shrink();
    }
     Widget getSolution (Option option , Question question) {
      final isSelected = option == question.selectedOption;
      if(question.isLocked) {
        if(isSelected){
          return option.isCorrect?Text(question.solution)
          :const Icon(Icons.cancel , color: Colors.red,);
        } else if (option.isCorrect) { 
          return Text(question.solution);
        }
      }
      return const SizedBox.shrink();
    }
   
    
}

I try to make a list of questions inside a list of categories and I didn't find how to add a list of questions to all the categories

0

There are 0 best solutions below