我是Flutter的新手。我尝试适应提供者。我有一个QuestionsScreen
小部件,它是用FutureBuilder
构建的,并且我将QuestionItem
用作项目生成器。我的visible
类具有AssessmentQuestion
属性,某些问题的选项可能会触发特定问题对该属性的更改。那么如何更改QuestionItem
上方列表中的属性?
我尝试使用Provider.of
,但不确定是否是这种方式。
// QuestionsScreen - builder
class QuestionsScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final QuestionsScreenArguments args = ModalRoute.of(context).settings.arguments;
return ChangeNotifierProvider(
builder: (_) => QuestionsState(),
child: FutureBuilder(
future: DbService.getAssessment(args.assessment.id),
builder: (BuildContext context, AsyncSnapshot snap) {
var state = Provider.of<QuestionsState>(context);
if (snap.hasData) {
List<AssessmentQuestion> questions = snap.data;
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.deepPurple,
title: Text(args.assessment.name),
actions: [
IconButton(
icon: Icon(FontAwesomeIcons.listAlt,
color: Colors.pink[200]),
onPressed: () => Navigator.pushNamed(context, '/assessments'),
)
],
),
body: GridView.count(
primary: false,
padding: const EdgeInsets.all(20.0),
crossAxisSpacing: 10.0,
crossAxisCount: 1,
children: questions.map((question) => QuestionItem(question: question)).toList(),
),
);
} else {
return LoadingScreen();
}
},
),
);
}
}
// Question Item -- here I want to achive dynamic change of visible or not
class QuestionItem extends StatelessWidget {
final AssessmentQuestion question;
QuestionItem({this.question});
@override
Widget build(BuildContext context) {
var state = Provider.of<QuestionsState>(context);
if (question.visible) {
return Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
padding: EdgeInsets.all(10),
alignment: Alignment.center,
child: Text(question.order.toString() + ') ' + question.text),
),
Container(
padding: EdgeInsets.all(12),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: question.options.map((opt) {
return Container(
height: 90,
margin: EdgeInsets.only(bottom: 10),
color: Colors.black26,
child: InkWell(
onTap: () {
state.selected(opt);
},
child: Container(
padding: EdgeInsets.all(16),
child: Row(
children: [
Icon(
state.selectedOptions.contains(opt)
? FontAwesomeIcons.checkCircle
: FontAwesomeIcons.circle,
size: 30,
color: state.selectedOptions.contains(opt) ? Colors.orange : Colors.grey),
Expanded(
child: Container(
margin: EdgeInsets.only(left: 16),
child: Text(
opt.text,
),
),
),
],
),
),
),
);
}).toList(),
),
)
],
);
} else {
return Column(
children: <Widget>[
Text('Not visible'),
],
);
}
}
}
// On option select this is called
void selected(Option newValue) {
List<dynamic> toRemove = [];
String questionType = newValue.question.type;
if (selectedOptions.contains(newValue)) {
toRemove.add(newValue);
} else {
switch(questionType) {
case 'singleChoice':
selectedOptions.forEach((opt) {
if (opt is Option && opt.question == newValue.question) {
toRemove.add(opt);
}
});
selectedOptions.add(newValue);
break;
case 'multipleChoice':
selectedOptions.add(newValue);
break;
default:
break;
}
if (newValue.question != null) {
newValue.question.visible = true;
}
}
selectedOptions.removeWhere((e) => toRemove.contains(e));
notifyListeners();
}
}
我希望在QuestionItem
中单击某个选项时显示相关问题。