Flutter 在颤振中洗牌期权的位置

Flutter 在颤振中洗牌期权的位置,flutter,dart,Flutter,Dart,有没有一种方法可以在flutter中洗牌问题和选项?就像在一个问题中,我在一张卡片上有4个答案选项,但只有一个是正确的。当我完成测试并再次尝试播放时,选项的顺序不会改变其位置,如图所示 所以,我希望卡片中的选项改变它的位置,比如从第一个到最后一个或任何位置。下面的代码是我如何做到这一点,得到一个问题列表 class Question { final int id, answer; final String question; final List<String> opt

有没有一种方法可以在flutter中洗牌问题和选项?就像在一个问题中,我在一张卡片上有4个答案选项,但只有一个是正确的。当我完成测试并再次尝试播放时,选项的顺序不会改变其位置,如图所示

所以,我希望卡片中的选项改变它的位置,比如从第一个到最后一个或任何位置。下面的代码是我如何做到这一点,得到一个问题列表

class Question {
  final int id, answer;
  final String question;
  final List<String> options;

  Question({this.id, this.question, this.answer, this.options});
}

List sample_data = [
  {
    "id": 1,
    "question":
        "Flutter is an open-source UI software development kit created by ______",
    "options": ['Apple', 'Google', 'Facebook', 'Microsoft'],
    "answer_index": 1,
  },
  {
    "id": 2,
    "question": "When google release Flutter.",
    "options": ['Jun 2017', 'Jun 2017', 'May 2017', 'May 2018'],
    "answer_index": 2,
  },
  {
    "id": 3,
    "question": "A memory location that holds a single letter or number.",
    "options": ['Double', 'Int', 'Char', 'Word'],
    "answer_index": 2,
  },
  {
    "id": 4,
    "question": "What command do you use to output data to the screen?",
    "options": ['Cin', 'Count>>', 'Cout', 'Output>>'],
    "answer_index": 2,
  },
];


问题控制者


import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
import 'package:get/state_manager.dart';
import 'package:quiz_app/models/Questions.dart';
import 'package:quiz_app/screens/score/score_screen.dart';
import 'package:quiz_app/screens/welcome/welcome_screen.dart';

// We use get package for our state management

class QuestionController extends GetxController
    with SingleGetTickerProviderMixin {
  // Lets animated our progress bar

  AnimationController _animationController;
  Animation _animation;
  // so that we can access our animation outside
  Animation get animation => this._animation;

  PageController _pageController;
  PageController get pageController => this._pageController;

  List<Question> _questions = sample_data
      .map(
        (question) => Question(
            id: question['id'],
            question: question['question'],
            options: question['options'],
            answer: question['answer_index']),
      )
      .toList()
        ..shuffle();
  List<Question> get questions => this._questions;

  bool _isAnswered = false;
  bool get isAnswered => this._isAnswered;

  int _correctAns;
  int get correctAns => this._correctAns;

  int _selectedAns;
  int get selectedAns => this._selectedAns;

  // for more about obs please check documentation
  RxInt _questionNumber = 1.obs;
  RxInt get questionNumber => this._questionNumber;

  int _numOfCorrectAns = 0;
  int get numOfCorrectAns => this._numOfCorrectAns;

  // called immediately after the widget is allocated memory
  @override
  void onInit() {
    // Our animation duration is 60 s
    // so our plan is to fill the progress bar within 60s
    _animationController =
        AnimationController(duration: Duration(seconds: 60), vsync: this);
    _animation = Tween<double>(begin: 0, end: 1).animate(_animationController)
      ..addListener(() {
        // update like setState
        update();
      });

    // start our animation
    // Once 30s is completed go to the next qn
    _animationController.forward().whenComplete(nextQuestion);
    _pageController = PageController();

    super.onInit();
    if (_questionNumber == _questions.length) {
      reset();
      Get.to(WelcomeScreen());
      _animationController.reset();
    }
  }

  // // called just before the Controller is deleted from memory
  @override
  void onClose() {
    super.onClose();
    _animationController.dispose();
    _pageController.dispose();
  }

  void checkAns(Question question, int selectedIndex) {
    // because once user press any option then it will run
    _isAnswered = true;
    _correctAns = question.answer;
    _selectedAns = selectedIndex;

    if (_correctAns == _selectedAns) _numOfCorrectAns++;

    // It will stop the counter
    _animationController.stop();
    update();

    // Once user select an ans after 2s it will go to the next qn
    Future.delayed(Duration(seconds: 1), () {
      nextQuestion();
    });
  }

  void nextQuestion() {
    if (_questionNumber.value != _questions.length) {
      _isAnswered = false;
      _pageController.nextPage(
          duration: Duration(milliseconds: 250), curve: Curves.ease);

      // Reset the counter
      _animationController.reset();

      // Then start it again
      // Once timer is finish go to the next qn
      _animationController.forward().whenComplete(nextQuestion);
    } else {
      // Get package provide us simple way to naviigate another page
      Get.to(ScoreScreen());
    }
  }

  void updateTheQnNum(int index) {
    _questionNumber.value = index + 1;
  }

  void reset() {
    _isAnswered = false;
    _correctAns = 0;
    _selectedAns = 0;
    _questionNumber = 1.obs;
    _numOfCorrectAns = 0;

    //Get.to(WelcomeScreen());
  }
}



导入“package:flatter/widgets.dart”;
导入“package:get/get.dart”;
导入“package:get/state_manager.dart”;
导入“package:quick_app/models/Questions.dart”;
导入“包:测验应用程序/屏幕/分数/分数屏幕.dart”;
导入“包:测验应用程序/屏幕/欢迎/欢迎屏幕.dart”;
//我们使用get包进行状态管理
类QuestionController扩展了GetxController
使用SingleGetTickerProviderMixin{
//让我们为进度条设置动画
AnimationController _AnimationController;
动画(动画),;
//这样我们就可以在外面看到我们的动画了
动画获取动画=>此;
页面控制器_页面控制器;
PageController获取PageController=>this.\u PageController;
列表问题=样本数据
.地图(
(问题)=>问题(
id:问题['id'],
问题:问题("问题"),,
选项:问题[“选项”],
答:问题("答案索引"),,
)
托利斯先生()
…洗牌();
列出获取问题=>这个;
bool_isAnswered=false;
bool get isAnswered=>这个;
国际校正者;
int get correctAns=>这个;
int_selectedAns;
int get selectedAns=>this.\u selectedAns;
//有关obs的更多信息,请查看文档
RxInt_问题编号=1.obs;
RxInt get questionNumber=>这个;
int _numOfCorrectAns=0;
int get numOfCorrectAns=>这个;
//在小部件分配内存后立即调用
@凌驾
void onInit(){
//我们的动画持续时间是60秒
//所以我们的计划是在60秒内填满进度条
_动画控制器=
AnimationController(持续时间:持续时间(秒数:60),vsync:this);
_animation=Tween(开始:0,结束:1)。设置动画(\u animationController)
…addListener(){
//像setState一样更新
更新();
});
//开始我们的动画
//完成30秒后,转到下一个qn
_animationController.forward()。完成时(下一个问题);
_pageController=pageController();
super.onInit();
如果(\u questionNumber==\u questions.length){
重置();
Get.to(WelcomeScreen());
_animationController.reset();
}
}
////在控制器从内存中删除之前调用
@凌驾
void onClose(){
super.onClose();
_animationController.dispose();
_pageController.dispose();
}
无效检查(问题,整数选择索引){
//因为一旦用户按下任何选项,它就会运行
_isAnswered=true;
_correctAns=问题。答案;
_selectedAns=selectedIndex;
如果(_correctAns==_selectedAns)_numOfCorrectAns++;
//它会让柜台停下来
_animationController.stop();
更新();
//一旦用户在2秒后选择ans,它将转到下一个qn
未来。延迟(持续时间(秒:1),(){
nextQuestion();
});
}
void nextQuestion(){
如果(\u questionNumber.value!=\u questions.length){
_isAnswered=假;
_pageController.nextPage(
持续时间:持续时间(毫秒:250),曲线:Curves.ease);
//重置计数器
_animationController.reset();
//然后重新开始
//计时器完成后,转到下一个qn
_animationController.forward()。完成时(下一个问题);
}否则{
//Get package为我们提供了导航另一页的简单方法
Get.to(ScoreScreen());
}
}
void updateTheQnNum(整数索引){
_questionNumber.value=索引+1;
}
无效重置(){
_isAnswered=假;
_correctAns=0;
_selectedAns=0;
_问题编号=1.0B;
_numOfCorrectAns=0;
//Get.to(WelcomeScreen());
}
}

我刚刚在darpad中制作了它,因此它不会重复代码中的所有小部件,而是对问题和选项进行洗牌,我认为它使用了您的模型

唯一的问题是我们也需要更改
answer
/
answer\u index
,因为列表是无序的,
answer\u index
将不正确,一个非常简单的方法是不使用索引检查答案,只使用答案的文本值(而不是索引)

也对其进行了编辑,这导致样本数据的结构发生了微小的变化,问题的模型也发生了微小的形式变化


课堂提问{
最终int id;
最后一道弦乐题;
最后清单选择;
最后的字符串答案;
问题:({
这个.id=0,
这个问题=“”,
this.options=const[],
这个答案是,
});
}
void main()异步{
列表样本_数据=[
{
“id”:1,
“问题”:
“Flatter是一个开源的UI软件开发工具包,由___;创建”,
“选项”:[‘苹果’、‘谷歌’、‘Facebook’、‘微软’],
回答:“苹果”,
},
{
“id”:2,
“问题”:“当谷歌发布颤振时。”,
“期权”:[‘2017年6月’、‘2017年6月’、‘2017年5月’、‘2018年5月’],
“答复”:“2017年6月”,
},
{
“id”:3,
“问题”:“保存单个字母或数字的内存位置。”,
“选项”:['Double','Int','Char','Word'],
“答案”:“加倍”,
},
{
“id”:4,
“问题”:“您使用什么命令将数据输出到屏幕?”,
“选项”:['Cin'、'Cout'、'Output>>'],
“答案”:“Cin”,
},
];
列表问题=示例_data.map((问题){
//洗牌
列表选项=问题[“选项”];
options.shuffle();

import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
import 'package:get/state_manager.dart';
import 'package:quiz_app/models/Questions.dart';
import 'package:quiz_app/screens/score/score_screen.dart';
import 'package:quiz_app/screens/welcome/welcome_screen.dart';

// We use get package for our state management

class QuestionController extends GetxController
    with SingleGetTickerProviderMixin {
  // Lets animated our progress bar

  AnimationController _animationController;
  Animation _animation;
  // so that we can access our animation outside
  Animation get animation => this._animation;

  PageController _pageController;
  PageController get pageController => this._pageController;

  List<Question> _questions = sample_data
      .map(
        (question) => Question(
            id: question['id'],
            question: question['question'],
            options: question['options'],
            answer: question['answer_index']),
      )
      .toList()
        ..shuffle();
  List<Question> get questions => this._questions;

  bool _isAnswered = false;
  bool get isAnswered => this._isAnswered;

  int _correctAns;
  int get correctAns => this._correctAns;

  int _selectedAns;
  int get selectedAns => this._selectedAns;

  // for more about obs please check documentation
  RxInt _questionNumber = 1.obs;
  RxInt get questionNumber => this._questionNumber;

  int _numOfCorrectAns = 0;
  int get numOfCorrectAns => this._numOfCorrectAns;

  // called immediately after the widget is allocated memory
  @override
  void onInit() {
    // Our animation duration is 60 s
    // so our plan is to fill the progress bar within 60s
    _animationController =
        AnimationController(duration: Duration(seconds: 60), vsync: this);
    _animation = Tween<double>(begin: 0, end: 1).animate(_animationController)
      ..addListener(() {
        // update like setState
        update();
      });

    // start our animation
    // Once 30s is completed go to the next qn
    _animationController.forward().whenComplete(nextQuestion);
    _pageController = PageController();

    super.onInit();
    if (_questionNumber == _questions.length) {
      reset();
      Get.to(WelcomeScreen());
      _animationController.reset();
    }
  }

  // // called just before the Controller is deleted from memory
  @override
  void onClose() {
    super.onClose();
    _animationController.dispose();
    _pageController.dispose();
  }

  void checkAns(Question question, int selectedIndex) {
    // because once user press any option then it will run
    _isAnswered = true;
    _correctAns = question.answer;
    _selectedAns = selectedIndex;

    if (_correctAns == _selectedAns) _numOfCorrectAns++;

    // It will stop the counter
    _animationController.stop();
    update();

    // Once user select an ans after 2s it will go to the next qn
    Future.delayed(Duration(seconds: 1), () {
      nextQuestion();
    });
  }

  void nextQuestion() {
    if (_questionNumber.value != _questions.length) {
      _isAnswered = false;
      _pageController.nextPage(
          duration: Duration(milliseconds: 250), curve: Curves.ease);

      // Reset the counter
      _animationController.reset();

      // Then start it again
      // Once timer is finish go to the next qn
      _animationController.forward().whenComplete(nextQuestion);
    } else {
      // Get package provide us simple way to naviigate another page
      Get.to(ScoreScreen());
    }
  }

  void updateTheQnNum(int index) {
    _questionNumber.value = index + 1;
  }

  void reset() {
    _isAnswered = false;
    _correctAns = 0;
    _selectedAns = 0;
    _questionNumber = 1.obs;
    _numOfCorrectAns = 0;

    //Get.to(WelcomeScreen());
  }
}