问题描述
我正在尝试构建测验应用程序。当任何用户开始参加测验时,计时器就会启动,并且不知道为什么每秒钟都会重新初始化所有内容。布尔参数“已回答”每秒设置为false。结果,参与者可以多次回答相同的问题,这将导致错误的结果并且不会发生。这是一个片段-
class MathQuizPlay extends StatefulWidget {
final String quizId;
MathQuizPlay({Key key,this.quizId}) : super(key: key);
@override
_MathQuizPlayState createState() => _MathQuizPlayState(this.quizId);
}
int total = 0;
int _correct = 0;
int _incorrect = 0;
int _notAttempted = 0;
int timer;
String showtimer;
class _MathQuizPlayState extends State<MathQuizPlay> {
var quizId;
_MathQuizPlayState(this.quizId);
QuerySnapshot questionSnapshot;
bool isLoading = true;
getQuestionData(String quizId) async {
return await Firestore.instance
.collection('math')
.document(quizId)
.collection('QNA')
.getDocuments();
}
@override
void initState() {
getQuestionData(quizId).then((value) {
questionSnapshot = value;
setState(() {
total = questionSnapshot.documents.length;
_correct = 0;
_incorrect = 0;
_notAttempted = questionSnapshot.documents.length;
isLoading = false;
timer = total * 15;
showtimer = timer.toString();
});
});
starttimer();
super.initState();
}
@override
void setState(fn) {
if (mounted) {
super.setState(fn);
}
}
Questions getQuestionModelFromDatasnapshot(
DocumentSnapshot questionSnapshot) {
final Questions questionModel = Questions(
question: questionSnapshot.data['question'],option1: questionSnapshot.data['option1'],option2: questionSnapshot.data['option2'],option3: questionSnapshot.data['option3'],option4: questionSnapshot.data['option4'],correctOption: questionSnapshot.data['correctOption'],answered: false);
return questionModel;
}
void starttimer() async {
const onesec = Duration(seconds: 1);
Timer.periodic(onesec,(Timer t) {
setState(() {
if (timer < 1) {
t.cancel();
Navigator.pushReplacement(
context,MaterialPageRoute(
builder: (context) => Result(
correct: _correct,incorrect: _incorrect,total: total,notattempt: _notAttempted,collection: 'math',quizId: quizId,)));
} else {
timer = timer - 1;
}
showtimer = timer.toString();
});
});
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.teal[300],title: Text("Questions",style: TextStyle(
color: Colors.white,)),elevation: 5.0,centerTitle: true,),body: isLoading
? Container(
child: Center(child: CircularProgressIndicator()),)
: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,children: <Widget>[
SizedBox(
height: 10,Center(
child: Container(
height: 60,width: 60,decoration: Boxdecoration(
borderRadius: BorderRadius.circular(36),border: Border.all(
width: 2.0,color: Colors.red.withOpacity(0.8),child: Center(
child: Text(
showtimer,style: TextStyle(
fontWeight: FontWeight.w500,fontSize: 19.0,color: Colors.red.withOpacity(0.8)),)))),SizedBox(
height: 10,Center(child: Text('Tap on the option to select answer')),questionSnapshot.documents == null
? Container(
child: Center(
child: Text("No Data"),)
: ListView.builder(
itemCount: questionSnapshot.documents.length,shrinkWrap: true,physics: ClampingScrollPhysics(),itemBuilder: (context,index) {
return Padding(
padding: const EdgeInsets.symmetric(
vertical: 15.0,horizontal: 25),child: QuizPlayTile(
questionModel: getQuestionModelFromDatasnapshot(
questionSnapshot.documents[index]),index: index,);
}),SizedBox(
height: 30,Center(
child: RaisedButton(
padding:
EdgeInsets.symmetric(vertical: 18,horizontal: 60),color: Colors.teal[300],textColor: Colors.white,shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(8.0)),child: Text(
'Submit',style: TextStyle(fontSize: 16),elevation: 7.0,onpressed: () {
Navigator.pushReplacement(
context,MaterialPageRoute(
builder: (context) => Result(
correct: _correct,)));
}),SizedBox(
height: 50,)
],);
}
}
解决方法
我也无法使用ChangeNotifierProvider解决问题。但是幸运的是我找到了一个可以完全解决我问题的软件包。因此,我使用该程序包而不是定期的Timer来设置时间。这是更新-
import 'package:circular_countdown_timer/circular_countdown_timer.dart';
class PhyQuizPlay extends StatefulWidget {
final String quizId;
PhyQuizPlay({Key key,this.quizId}) : super(key: key);
@override
_PhyQuizPlayState createState() => _PhyQuizPlayState(this.quizId);
}
int total = 0;
int _correct = 0;
int _incorrect = 0;
int _notAttempted = 0;
int timer;
class _PhyQuizPlayState extends State<PhyQuizPlay> {
var quizId;
_PhyQuizPlayState(this.quizId);
QuerySnapshot questionSnapshot;
bool isLoading = true;
getQuestionData(String quizId) async {
return await Firestore.instance
.collection('physics')
.document(quizId)
.collection('QNA')
.getDocuments();
}
@override
void initState() {
getQuestionData(quizId).then((value) {
questionSnapshot = value;
setState(() {
total = questionSnapshot.documents.length;
_correct = 0;
_incorrect = 0;
_notAttempted = total;
isLoading = false;
timer = total * 15;
});
});
super.initState();
}
Questions getQuestionModelFromDatasnapshot(
DocumentSnapshot questionSnapshot) {
final Questions questionModel = Questions(
question: questionSnapshot.data['question'],option1: questionSnapshot.data['option1'],option2: questionSnapshot.data['option2'],option3: questionSnapshot.data['option3'],option4: questionSnapshot.data['option4'],correctOption: questionSnapshot.data['correctOption'],answered: false);
return questionModel;
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.teal[300],title: Text("Questions",style: TextStyle(
color: Colors.white,)),elevation: 5.0,centerTitle: true,),body: isLoading
? Container(
child: Center(child: CircularProgressIndicator()),)
: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,children: <Widget>[
SizedBox(
height: 10,Center(
child: CircularCountDownTimer(
width: 80,height: 80,duration: timer,fillColor: Colors.red,color: Colors.white38,isReverse: true,onComplete: () {
Navigator.pushReplacement(
context,MaterialPageRoute(
builder: (context) => Result(
correct: _correct,incorrect: _incorrect,total: total,notattempt: _notAttempted,collection: 'physics',quizId: quizId,)));
},SizedBox(
height: 10,Center(child: Text('Tap on the option to select answer')),questionSnapshot.documents == null
? Center(
child: CircularProgressIndicator(),)
: ListView.builder(
itemCount: questionSnapshot.documents.length,shrinkWrap: true,physics: ClampingScrollPhysics(),itemBuilder: (context,index) {
return Padding(
padding: const EdgeInsets.symmetric(
vertical: 15.0,horizontal: 25),child: QuizPlayTile(
questionModel: getQuestionModelFromDatasnapshot(
questionSnapshot.documents[index]),index: index,);
}),SizedBox(
height: 30,Center(
child: RaisedButton(
padding:
EdgeInsets.symmetric(vertical: 18,horizontal: 60),color: Colors.teal[300],textColor: Colors.white,shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(8.0)),child: Text(
'Submit',style: TextStyle(fontSize: 16),elevation: 7.0,onPressed: () {
Navigator.pushReplacement(
context,MaterialPageRoute(
builder: (context) => Result(
correct: _correct,)));
}),SizedBox(
height: 50,)
],);
}
}