如何解决当我回来或完成时如何重置我的控制器?
我有一个 QuestionController 类 extends GetxController
当我使用控件退出页面时,我希望它停止工作(因为它仍在后台运行)并在我返回该页面时重新启动。
我已经尝试过:我在 ScoreScreen()
的路线之后添加了这些(在 nextQuestion ()
中):
_isAnswered = false;
_questionNumber.value = 1;
我在进入分数页面之前重置了数值。如果您转到分数页面,它可能会起作用,但是如果您早点回来,则不会。 (问题 num/4 在这里不起作用)。所以这种方式不适合。
当页面退出时,我可以通过什么方式停止并重置它?
控制器类代码:
class QuestionController extends GetxController
with SingleGetTickerProviderMixin {
PageController _pageController;
PageController get pageController => this._pageController;
List<Question> _questions = questions_data
.map(
(e) => Question(
id: e["id"],question: e["question"],options: e["options"],answer: e["answer_index"]),)
.toList();
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;
RxInt _questionNumber = 1.obs;
RxInt get questionNumber => this._questionNumber;
int _numOfCorrectAns = 0;
int get numOfCorrectAns => this._numOfCorrectAns;
@override
void onInit() {
_pageController = PageController();
super.onInit();
}
@override
void onClose() {
super.onClose();
_pageController.dispose();
}
void checkAns(Question question,int selectedIndex) {
_isAnswered = true;
_correctAns = question.answer;
_selectedAns = selectedIndex;
if (_correctAns == _selectedAns) _numOfCorrectAns++;
update();
Future.delayed(Duration(seconds: 2),() {
nextQuestion();
});
}
void nextQuestion() {
if (_questionNumber.value != _questions.length) {
_isAnswered = false;
_pageController.nextPage(
duration: Duration(milliseconds: 300),curve: Curves.ease);
} else {
Get.off(ScoreScreen(correctNum: _numOfCorrectAns)); // GetMaterialApp()
// _isAnswered = false;
_numOfCorrectAns = 0;
//_questionNumber.value = 1;
}
}
void updateTheQuestionNum(int index) {
_questionNumber.value = index + 1;
}
}
完整代码如下
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:get/get.dart'; // get: ^3.25.4
// QuizPage() ===============> 50. line (Question 1/4) 81. line
// QuestionCard() ==============> 116. line
// Option() ===================> 163. line
// QuestionController() ========> 218. line
// ScoreScreen() ================> 345. line
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
debugShowCheckedModeBanner: false,theme: ThemeData(canvasColor: Colors.blue),home: HomeScreen(),);
}
}
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Home Page"),),body: Center(
child: InkWell(
onTap: () {
Navigator.push(
context,MaterialPageRoute(builder: (context) => QuizPage()));
},child: Container(
padding: EdgeInsets.all(22),color: Colors.green,child: Text(
"Go Quiz Page",style: TextStyle(color: Colors.white),);
}
}
class QuizPage extends StatelessWidget {
const QuizPage({
Key key,}) : super(key: key);
@override
Widget build(BuildContext context) {
QuestionController _questionController = Get.put(QuestionController());
return Scaffold(
appBar: AppBar(
title: Text("Quiz Page"),body: Stack(
children: [
SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,children: [
SizedBox(
height: 16,Padding(
padding: EdgeInsets.symmetric(horizontal: 16),child: Obx(
() => Center(
child: RichText(
text: TextSpan(
// text,style default adjust here OR:children[TextSpan(1,adjust 1),TextSpan(2,adjust 2),..]
text:
"Question ${_questionController._questionNumber.value}",style: TextStyle(
fontSize: 33,color: Colors.white70),children: [
TextSpan(
text:
"/${_questionController._questions.length}",style: TextStyle(fontSize: 25))
])),Divider(color: Colors.white70,thickness: 1),SizedBox(
height: 16,Expanded(
child: PageView.builder(
physics: NeverScrollableScrollPhysics(),controller: _questionController._pageController,onPageChanged: _questionController.updateTheQuestionNum,itemCount: _questionController.questions.length,itemBuilder: (context,index) => QuestionCard(
question: _questionController.questions[index],)
],)
],);
}
}
class QuestionCard extends StatelessWidget {
final Question question;
const QuestionCard({
Key key,@required this.question,}) : super(key: key);
@override
Widget build(BuildContext context) {
QuestionController _controller = Get.put(QuestionController());
return Container(
margin: EdgeInsets.only(left: 16,right: 16,bottom: 16),padding: EdgeInsets.all(16),decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25),color: Colors.white,child: Column(
children: [
Text(
question.question,style: TextStyle(fontSize: 22),SizedBox(
height: 8,Flexible(
child: SingleChildScrollView(
child: Column(
children: [
...List.generate(
question.options.length,(index) => Option(
text: question.options[index],index: index,press: () => _controller.checkAns(question,index)))
],);
}
}
class Option extends StatelessWidget {
final String text;
final int index;
final VoidCallback press;
const Option({
Key key,@required this.text,@required this.index,@required this.press,}) : super(key: key);
@override
Widget build(BuildContext context) {
return GetBuilder<QuestionController>(
init: QuestionController(),builder: (q) {
Color getRightColor() {
if (q.isAnswered) {
if (index == q._correctAns) {
return Colors.green;
} else if (index == q.selectedAns &&
q.selectedAns != q.correctAns) {
return Colors.red;
}
}
return Colors.blue;
}
return InkWell(
onTap: press,child: Container(
//-- Option
margin: EdgeInsets.only(top: 16),decoration: BoxDecoration(
color: getRightColor(),borderRadius: BorderRadius.circular(16)),child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,children: [
Text(
"${index + 1}. $text",style: TextStyle(fontSize: 16,color: Colors.white),],);
});
}
}
class QuestionController extends GetxController
with SingleGetTickerProviderMixin {
PageController _pageController;
PageController get pageController => this._pageController;
List<Question> _questions = questions_data
.map(
(e) => Question(
id: e["id"],)
.toList();
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;
RxInt _questionNumber = 1.obs;
RxInt get questionNumber => this._questionNumber;
int _numOfCorrectAns = 0;
int get numOfCorrectAns => this._numOfCorrectAns;
@override
void onInit() {
_pageController = PageController();
//_pageController.addListener(() { _questionNumber.value = _pageController.page.round()+1; });
super.onInit();
}
@override
void onClose() {
super.onClose();
_pageController.dispose();
}
void checkAns(Question question,curve: Curves.ease);
} else {
Get.off(ScoreScreen(correctNum: _numOfCorrectAns)); // GetMaterialApp()
// _isAnswered = false;
_numOfCorrectAns = 0;
//_questionNumber.value = 1;
}
}
void updateTheQuestionNum(int index) {
_questionNumber.value = index + 1;
}
}
class Question {
final int id,answer;
final String question;
final List<String> options;
Question({
@required this.id,@required this.options,@required this.answer,});
}
const List questions_data = [
{
"id": 1,"question": "Question 1","options": ['option A','B','C','D'],"answer_index": 3,},{
"id": 2,"question": "Question 2","answer_index": 2,{
"id": 3,"question": "Question 3","answer_index": 0,{
"id": 4,"question": "Question 4",];
class ScoreScreen extends StatelessWidget {
final int correctNum;
ScoreScreen({@required this.correctNum});
@override
Widget build(BuildContext context) {
QuestionController _qController = Get.put(QuestionController());
return Scaffold(
body: Stack(
fit: StackFit.expand,children: [
Column(
children: [
Spacer(
flex: 2,Text(
"Score",style: TextStyle(fontSize: 55,Spacer(),Text(
"${correctNum * 10}/${_qController.questions.length * 10}",style: TextStyle(fontSize: 33,Spacer(
flex: 2,InkWell(
onTap: () => Get.back(),borderRadius: BorderRadius.circular(16),child: Container(
padding: EdgeInsets.all(16),decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),color: Colors.white24),child: Text(
"Back to Home Page",);
}
}
解决方法
更新答案:
好的,在看到您的完整代码后,我的解决方案需要几个额外的步骤。
将此添加到您的控制器类。它需要在您的 HomeScreen
void resetQuestionNumber() => _questionNumber.value = 1;
您必须提前初始化控制器,以便将其添加到您的 HomeScreen
final _questionController = Get.put(QuestionController());
您的 onTap
的 HomeScreen
现在看起来像这样。
onTap: () {
_questionController.resetQuestionNumber();
Navigator.push(
context,MaterialPageRoute(builder: (context) => QuizPage()));
},
应该可以。 _pageController
索引直到问题得到回答后才会更新,因此只需在转到 _questionNumber
之前重置 QuizPage
,然后它就会赶上。您的 updateTheQuestionNum
可以完全消失,您无需再在 onPageChanged
的 PageView.builder
中处理任何此类事情。
原答案:
如果您只是想让 RxInt _questionNumber
与 _pageController
的值相匹配,您可以在 onInit
中添加一个监听器
_pageController.addListener(() {
_questionNumber.value = _pageController.page.round() + 1;
});
编辑:添加 + 1 以说明从 0 开始的索引
,你可以监听“onBack 事件”并配置控制器 这是一个例子
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {
disposeController(context);
},child: Scaffold(
key: _scaffoldKey,appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back),onPressed: () {
_moveToSignInScreen(context);
}),title: Text("Profile"),),);
}
void disposeController(BuildContext context){
//or what you wnat to dispose/clear
_pageController.dispose()
}
,
如果你只有一个控制器,你可以使用 Get.reset()。它会清除所有注册的实例。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。