我有一个QuestionController类扩展了GetxController
当我使用控件退出Page时,我希望它停止工作(因为它仍在后台运行),并在我返回该页面时重新启动。
我试过了:我在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),
padding: EdgeInsets.all(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"],
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();
//_pageController.addListener(() { _questionNumber.value = _pageController.page.round()+1; });
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;
}
}
class Question {
final int id, answer;
final String question;
final List<String> options;
Question({
@required this.id,
@required this.question,
@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",
"options": ['option A', 'B', 'C', 'D'],
"answer_index": 2,
},
{
"id": 3,
"question": "Question 3",
"options": ['option A', 'B', 'C', 'D'],
"answer_index": 0,
},
{
"id": 4,
"question": "Question 4",
"options": ['option A', 'B', 'C', 'D'],
"answer_index": 0,
},
];
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, color: Colors.white),
),
Spacer(),
Text(
"${correctNum * 10}/${_qController.questions.length * 10}",
style: TextStyle(fontSize: 33, color: Colors.white),
),
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",
style: TextStyle(color: Colors.white),
),
),
),
Spacer(),
],
),
],
),
);
}
}
6条答案
按热度按时间c86crjj01#
如果您只想重置一个控制器,则可以使用
Get.delete<ExecutableController>();
用于复位所有控制器
Get.deleteAll();
u7up0aaq2#
更新的答案:
好的,在看到你的完整代码后,我的解决方案需要几个额外的步骤。
将其添加到您的控制器类中。它需要在
HomeScreen
的onPressed中调用您必须更早地初始化控制器,以便将其添加到您的
HomeScreen
中HomeScreen
的onTap
现在如下所示。这样就可以了。
_pageController
索引直到问题被回答后才更新,所以你只需要在转到QuizPage
之前重置_questionNumber
,然后它就会追上来。你的updateTheQuestionNum
可以完全消失,你不再需要在PageView.builder
的onPageChanged
中处理任何事情。原始答案:
如果只想让
RxInt _questionNumber
与_pageController
的值匹配,则可以在onInit
中添加一个侦听器编辑:为从0开始的索引添加了+ 1
iklwldmw3#
您可以侦听“onBack事件”并释放控制器,下面是一个示例
}
oaxa6hgo4#
),
jhkqcmku5#
自动执行:
手动操作:
U可以删除控制器上回来btn然后把它再次它会给同样的结果重置控制器:
1.删除它:
删除();
1.再加一句:
获取. put( Jmeter 板控制器());
z9gpfhce6#
如果只有一个控制器,可以使用
Get.reset()
。它会清除所有注册的示例。