Я хочу знать, как поставить число вопросов от 1 до 40, чтобы отобразить пользователей, на какие вопросы он пришел в викторине. Он также должен быть доступен для случайного массива. Отображается только от 1 до 40 на одной странице. Данные извлекаются из автономной базы данных на моем локальном компьютере.
Буду признателен, если я смогу это сделать.
Спасибо.
class getjson extends StatelessWidget {
String langname;
getjson(this.langname);
String assettoload;
setasset() {
if (langname == "Test Paper 1") {
assettoload = "assets/test1.json";
} else if (langname == "Test Paper 2") {
assettoload = "assets/test2.json";
} else if (langname == "Test Paper 3") {
assettoload = "assets/test3.json";
} else if (langname == "Test Paper 4") {
assettoload = "assets/test4.json";
} else {
assettoload = "assets/test5.json";
}
}
@override
Widget build(BuildContext context) {
setasset();
return FutureBuilder(
future:
DefaultAssetBundle.of(context).loadString(assettoload, cache: true),
builder: (context, snapshot) {
List mydata = json.decode(snapshot.data.toString());
if (mydata == null) {
return Scaffold(body: Loading());
} else {
print(mydata[1]["1"]);
return QuizPage(
mydata: shuffle(mydata),
testName: langname,
);
}
},
);
}
List shuffle(List items) {
var random = new Random();
//randomize questions, answers and images
// Go through all elements.
for (var i = items[0].length - 1; i > 0; i--) {
// Pick a pseudorandom number according to the list length
var n = random.nextInt(i + 1);
print(n);
n == 0 ? n = 10 : n = n;
// questions
var temp = items[0]["$i"];
items[0]["$i"] = items[0]["$n"];
items[0]["$n"] = temp;
// answers
temp = items[1]["$i"];
items[1]["$i"] = items[1]["$n"];
items[1]["$n"] = temp;
// correct answers
temp = items[2]["$i"];
items[2]["$i"] = items[2]["$n"];
items[2]["$n"] = temp;
// images
temp = items[3]["$i"];
items[3]["$i"] = items[3]["$n"];
items[3]["$n"] = temp;
}
return items;
}
}
class QuizPage extends StatefulWidget {
var mydata;
final String testName;
QuizPage({Key key, @required this.mydata, this.testName}) : super(key: key);
@override
_QuizPageState createState() => _QuizPageState(mydata);
}
class _QuizPageState extends State<QuizPage> {
var mydata;
_QuizPageState(this.mydata);
//colour of buttons
Color colortoshow = Colors.indigoAccent;
Color right = Colors.green[300];
Color wrong = Colors.red[300];
int marks = 0;
int i = 1;
int j = 1;
int timer = 30;
String showtimer = "30";
int ques = 1;
String count = "1";
//default color of buttons
Map<String, Color> btncolor = {
"a": Colors.blue[200],
"b": Colors.blue[200],
"c": Colors.blue[200],
//"d": Colors.indigoAccent,
};
bool canceltimer = false;
//array of position numbers
var random_array = [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40
];
// overriding the initstate function to start timer as this screen is created
@override
void initState() {
starttimer();
super.initState();
}
// overriding the setstate function to be called only if mounted
@override
void setState(fn) {
if (mounted) {
super.setState(fn);
}
}
// counter
//timer
void starttimer() async {
const onesec = Duration(seconds: 1);
Timer.periodic(onesec, (Timer t) {
setState(() {
if (timer < 1) {
t.cancel();
nextquestion();
} else if (canceltimer == true) {
t.cancel();
} else {
timer = timer - 1;
}
showtimer = timer.toString();
});
});
}
void quesCount(){
setState(() {
if (mydata[0][i.toString()] <= mydata[0][39]) {
ques= ques +1;
}
else{
ques= ques;
}
});
count= ques.toString();
}
void nextquestion() {
canceltimer = false;
timer = 30;
setState(() {
if (j < 40) {
i = random_array[j];
j++;
} else {
String currentTime = DateTime.now().millisecondsSinceEpoch.toString();
Firestore.instance
.collection('users')
.document(QuizApp.sharedPreferences.getString('users'))
.collection(QuizApp.collectionScores)
.document(currentTime)
.setData({
'testName': widget.testName,
'marks': marks,
'timestamp': currentTime
});
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => ResultPage(
marks: marks,
testName: widget.testName,
),
));
}
btncolor["a"] = Colors.blue[200];
btncolor["b"] = Colors.blue[200];
btncolor["c"] = Colors.blue[200];
});
starttimer();
}
void checkanswer(String k) {
if (mydata[2][i.toString()] == mydata[1][i.toString()][k]) {
marks = marks + 1;
// changing the color variable to be green
colortoshow = right;
} else {
colortoshow = wrong;
}
setState(() {
// apply the changed color to the particular button that was selected
btncolor[k] = colortoshow;
canceltimer = true;
});
// timer increases by 1 second
Timer(Duration(seconds: 1), nextquestion);
}
//define button characteristics
Widget choicebutton(String k) {
return Padding(
padding: EdgeInsets.symmetric(
vertical: 10.0,
horizontal: 20.0,
),
child: MaterialButton(
onPressed: () => checkanswer(k),
child: Text(
mydata[1][i.toString()][k] == null
? "Error loading text"
: mydata[1][i.toString()][k],
textAlign: TextAlign.center,
style: GoogleFonts.roboto(
color: Colors.white,
fontSize: 16.0,
),
maxLines: 2,
),
color: btncolor[k],
splashColor: Colors.blue[200],
highlightColor: Colors.blue[200],
minWidth: 400.0,
height: 50.0,
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
),
);
}
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitDown, DeviceOrientation.portraitUp]);
return WillPopScope(
onWillPop: () {
//pop up msg if try to go back during quiz
return showDialog(
context: context,
builder: (context) => CupertinoAlertDialog(
title: Text("MoLaRoute",
style: GoogleFonts.roboto(
fontWeight: FontWeight.bold,
color: Hexcolor('#335C67'))),
content: Text("You can't go back at this stage.",
style: GoogleFonts.roboto()),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('Okay',
style:
GoogleFonts.roboto(fontWeight: FontWeight.bold)),
)
],
));
},
//get question from json
child: Scaffold(
body: Column(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
alignment: Alignment.topCenter,
child: Center(
child: Text(
count,
style: GoogleFonts.roboto(
fontSize: 35.0,
fontWeight: FontWeight.w700,
),
),
),
),
),
Expanded(
flex: 3,
child: Container(
padding: EdgeInsets.all(15.0),
alignment: Alignment.center,
child: Text(
mydata[0][i.toString()] == null
? "Error loading text"
: mydata[0][i.toString()],
style: GoogleFonts.roboto(
fontSize: 22.0, fontWeight: FontWeight.w400),
textAlign: TextAlign.justify,
),
),
),
//get image from json
Expanded(
flex: 3,
child: Container(
padding: EdgeInsets.all(10.0),
alignment: Alignment.center,
child: mydata[3][i.toString()] == null
? "Error loading Image"
: Image.asset(mydata[3][i.toString()]),
),
),
//get buttons
Expanded(
flex: 6,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
choicebutton('a'),
choicebutton('b'),
choicebutton('c'),
],
),
),
),
//get timer
Expanded(
flex: 1,
child: Container(
alignment: Alignment.topCenter,
child: Center(
child: Text(
showtimer,
style: GoogleFonts.roboto(
fontSize: 35.0,
fontWeight: FontWeight.w700,
),
),
),
),
),
],
),
),
);
}
}