I created the following observable variables:
``` @observable
ObservableList<bool> optionsSelecteds = ObservableList<bool>();
@observable
ObservableList<String> labelSelecteds = ObservableList<String>();
@observable
String selectedOption = '';
```
and on my page I call the following widget:
```Observer(
builder: (context) {
return SingleChildScrollView(
child: widget.options!.isNotEmpty
? ListView.builder(
shrinkWrap: true,
itemCount: widget.options!.length,
itemBuilder: (context, index) {
return QuizzOptionButtons(
title: widget.options![index],
onTap: () {
controller.ChangeSelectedOptions(
widget.options![index]);
controller.onSelect(index, widget.options!,
widget.isMultipleChoice!);
debugPrint(widget.options![index]);
debugPrint(
controller.optionsSelecteds.toString());
debugPrint(
controller.labelSelecteds.toString());
},
isSelected: controller.optionsSelecteds[index],
isMultipleChoice: widget.isMultipleChoice!,
options: widget.options,
index: index,
);
},
)
: const Center(child: Text('Nenhuma opção disponível')),
);
},
),```
```
Basically I'm mapping buttons for a quiz. My actions are:
```@action
void isSelectedList(List<dynamic> options, bool isMultipleChoice) {
optionsSelecteds.clear();
labelSelecteds.clear();
if (options.isNotEmpty) {
for (var element in options) {
labelSelecteds.add('');
optionsSelecteds.add(false);
}
}
}
@action
void onSelect(int index, List<dynamic> options, bool isMultipleChoice) {
optionsSelecteds[index] = !optionsSelecteds[index];
labelSelecteds[index] == ''
? labelSelecteds[index] = selectedOption
: labelSelecteds[index] = '';
for (int i = 0; i < optionsSelecteds.length; i++) {
if (i == index) {
optionsSelecteds[i] = true;
selectedOption = options[index];
} else {
optionsSelecteds[i] = false;
labelSelecteds[i] = '';
}
}
}
@action
void ChangeSelectedOptions(String option) {
selectedOption = option;
}```
and my complete widget looks like this:
```import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:flutter_modular/flutter_modular.dart';
import '../controller/quizz_store.dart';
class QuizzOptionButtons extends StatefulWidget {
final String title;
final bool isSelected;
final List<dynamic>? options;
final int index;
final VoidCallback onTap;
final bool isMultipleChoice;
const QuizzOptionButtons({
Key? key,
required this.title,
required this.isSelected,
required this.onTap,
this.isMultipleChoice = false,
required this.options,
required this.index,
}) : super(key: key);
@override
_QuizzOptionButtonsState createState() => _QuizzOptionButtonsState();
}
class _QuizzOptionButtonsState extends State<QuizzOptionButtons> {
final controller = Modular.get<QuizzStore>();
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: widget.onTap,
child: Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 20),
margin: const EdgeInsets.symmetric(vertical: 8),
decoration: BoxDecoration(
color: widget.isSelected ? Colors.green : const Color(0xFF111827),
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: widget.isSelected ? Colors.green.shade300 : Colors.grey,
width: 2,
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 5,
offset: const Offset(0, 2),
)
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
widget.title,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: widget.isSelected ? Colors.white : Colors.white,
),
),
if (widget.isMultipleChoice)
Icon(
widget.isSelected
? Icons.check_circle
: Icons.check_circle_outline,
color: widget.isSelected ? Colors.white : Colors.grey,
),
],
),
),
);
}
}```
I've literally been trying to figure out why my UI won't update for 4 hours, what am I doing wrong? What's the correct way to do this?
I created the following observable variables:
``` @observable
ObservableList<bool> optionsSelecteds = ObservableList<bool>();
@observable
ObservableList<String> labelSelecteds = ObservableList<String>();
@observable
String selectedOption = '';
```
and on my page I call the following widget:
```Observer(
builder: (context) {
return SingleChildScrollView(
child: widget.options!.isNotEmpty
? ListView.builder(
shrinkWrap: true,
itemCount: widget.options!.length,
itemBuilder: (context, index) {
return QuizzOptionButtons(
title: widget.options![index],
onTap: () {
controller.ChangeSelectedOptions(
widget.options![index]);
controller.onSelect(index, widget.options!,
widget.isMultipleChoice!);
debugPrint(widget.options![index]);
debugPrint(
controller.optionsSelecteds.toString());
debugPrint(
controller.labelSelecteds.toString());
},
isSelected: controller.optionsSelecteds[index],
isMultipleChoice: widget.isMultipleChoice!,
options: widget.options,
index: index,
);
},
)
: const Center(child: Text('Nenhuma opção disponível')),
);
},
),```
```
Basically I'm mapping buttons for a quiz. My actions are:
```@action
void isSelectedList(List<dynamic> options, bool isMultipleChoice) {
optionsSelecteds.clear();
labelSelecteds.clear();
if (options.isNotEmpty) {
for (var element in options) {
labelSelecteds.add('');
optionsSelecteds.add(false);
}
}
}
@action
void onSelect(int index, List<dynamic> options, bool isMultipleChoice) {
optionsSelecteds[index] = !optionsSelecteds[index];
labelSelecteds[index] == ''
? labelSelecteds[index] = selectedOption
: labelSelecteds[index] = '';
for (int i = 0; i < optionsSelecteds.length; i++) {
if (i == index) {
optionsSelecteds[i] = true;
selectedOption = options[index];
} else {
optionsSelecteds[i] = false;
labelSelecteds[i] = '';
}
}
}
@action
void ChangeSelectedOptions(String option) {
selectedOption = option;
}```
and my complete widget looks like this:
```import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:flutter_modular/flutter_modular.dart';
import '../controller/quizz_store.dart';
class QuizzOptionButtons extends StatefulWidget {
final String title;
final bool isSelected;
final List<dynamic>? options;
final int index;
final VoidCallback onTap;
final bool isMultipleChoice;
const QuizzOptionButtons({
Key? key,
required this.title,
required this.isSelected,
required this.onTap,
this.isMultipleChoice = false,
required this.options,
required this.index,
}) : super(key: key);
@override
_QuizzOptionButtonsState createState() => _QuizzOptionButtonsState();
}
class _QuizzOptionButtonsState extends State<QuizzOptionButtons> {
final controller = Modular.get<QuizzStore>();
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: widget.onTap,
child: Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 20),
margin: const EdgeInsets.symmetric(vertical: 8),
decoration: BoxDecoration(
color: widget.isSelected ? Colors.green : const Color(0xFF111827),
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: widget.isSelected ? Colors.green.shade300 : Colors.grey,
width: 2,
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 5,
offset: const Offset(0, 2),
)
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
widget.title,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: widget.isSelected ? Colors.white : Colors.white,
),
),
if (widget.isMultipleChoice)
Icon(
widget.isSelected
? Icons.check_circle
: Icons.check_circle_outline,
color: widget.isSelected ? Colors.white : Colors.grey,
),
],
),
),
);
}
}```
I've literally been trying to figure out why my UI won't update for 4 hours, what am I doing wrong? What's the correct way to do this?
Share Improve this question asked Mar 28 at 0:48 Yuri TrindadeYuri Trindade 11 bronze badge1 Answer
Reset to default 0Modify the onSelect
method to reassign the ObservableList
:
@action
void onSelect(int index, List<dynamic> options, bool isMultipleChoice) {
// Create a copy of the list and modify it
final updatedOptions = List<bool>.from(optionsSelecteds);
final updatedLabels = List<String>.from(labelSelecteds);
for (int i = 0; i < updatedOptions.length; i++) {
if (i == index) {
updatedOptions[i] = true;
updatedLabels[i] = selectedOption;
selectedOption = options[index];
} else {
updatedOptions[i] = false;
updatedLabels[i] = '';
}
}
// Reassign the lists to trigger UI updates
optionsSelecteds = ObservableList.of(updatedOptions);
labelSelecteds = ObservableList.of(updatedLabels);
}