0
I have the screen below that is controlled by MOBX, for some reason the scaffold when it falls into condition it ends up being presented several times in a row.
class ScheduleEnableScheduleScreen extends StatefulWidget {
@override
_ScheduleEnableScheduleScreenState createState() =>
_ScheduleEnableScheduleScreenState();
}
class _ScheduleEnableScheduleScreenState
extends State<ScheduleEnableScheduleScreen> {
ScheduleStore scheduleStore = ScheduleStore();
final _scaffoldKey = GlobalKey<ScaffoldState>();
@override
void initState() {
super.initState();
scheduleStore.loadingInitOptionsSchedule();
}
ReactionDisposer disposer;
@override
void didChangeDependencies() {
super.didChangeDependencies();
disposer = reaction((_) => scheduleStore.enableScheduleOk, (created) async {
if (created) {
_scaffoldKey.currentState.showSnackBar(SnackBar(
content: Text(
'Agenda cadastrada com sucesso!',
style: TextStyle(color: Colors.black),
),
backgroundColor: Colors.blueAccent,
duration: Duration(seconds: 2),
));
await Future.delayed(Duration(seconds: 2));
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => BaseScreen()));
}
});
disposer =
reaction((_) => scheduleStore.enableScheduleError, (created) async {
if (created) {
_scaffoldKey.currentState.showSnackBar(SnackBar(
content: Text(
'Error ao cadastrar',
style: TextStyle(color: Colors.black),
),
backgroundColor: Colors.red,
duration: Duration(seconds: 2),
));
}
await Future.delayed(Duration(seconds: 2));
});
}
@override
Widget build(BuildContext context) {
return Observer(
builder: (_) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text('Habilitar agenda'),
centerTitle: true,
backgroundColor: colorAppbar,
),
body: scheduleStore.loadingPageScheduleTime
? Center(child: CircularProgressIndicator())
: Container(
padding: EdgeInsets.only(top: 10.0, left: 16.0, right: 16.0),
color: Colors.white,
child: ListView(
children: <Widget>[
Container(
padding:
EdgeInsets.symmetric(horizontal: 60, vertical: 6),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(32),
color: colorCard),
child: DropdownButton(
hint: Text(
'Selecione o tipo de funcionário',
),
value: scheduleStore.valueSelectTypeEmployee,
items: scheduleStore.employeeDto.typeEmployees
.map((item) {
return DropdownMenuItem(
child: Text(item.description),
value: item.description,
);
}).toList(),
onChanged: (value) {
scheduleStore.selectTypeService(value);
scheduleStore.setIdTypeEmployee(value);
},
),
),
SizedBox(height: space),
CustomForm(
enabled: !scheduleStore.enableScheduleSending,
controller: scheduleStore.controllerDayInit,
tip: 'Data início',
label: 'Data início',
obscure: false,
ontap: () {
FocusScope.of(context).requestFocus(new FocusNode());
changeAlterDayIni();
},
onChanged: scheduleStore.setDayIni,
),
SizedBox(height: space),
CustomForm(
enabled: !scheduleStore.enableScheduleSending,
controller: scheduleStore.controllerAttendanceTime,
tip: 'HH:MM',
label: 'Tempo atendimento',
obscure: false,
ontap: () {
FocusScope.of(context).requestFocus(new FocusNode());
changeAlterHours(
scheduleStore.controllerAttendanceTime,
scheduleStore.setAttendanceTime);
},
),
SizedBox(height: space),
CustomForm(
enabled: !scheduleStore.enableScheduleSending,
controller: scheduleStore.controllerQuantityDays,
tip: 'Quantidade de dias',
label: 'Quantidade de dias',
obscure: false,
textInputType: TextInputType.number,
onChanged: scheduleStore.setQuantityDays,
),
SizedBox(height: space),
Container(
height: 60,
alignment: Alignment.centerLeft,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
stops: [0.3, 1],
colors: [
Color(0XFF212121),
Color(0XFF616161),
],
),
borderRadius: BorderRadius.all(
Radius.circular(50),
),
),
child: SizedBox.expand(
child: FlatButton(
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'Cadastrar',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 20),
textAlign: TextAlign.center,
),
Container(
child: SizedBox(
child:
scheduleStore.enableScheduleSending
? CircularProgressIndicator(
valueColor:
AlwaysStoppedAnimation(
Colors.blue),
)
: Icon(Icons.send),
height: 28,
width: 28,
),
)
],
),
onPressed:
scheduleStore.buttonEnableSchedulePressed)),
),
],
),
),
);
},
);
}
void changeAlterDayIni() {
DatePicker.showDatePicker(context,
locale: DateTimePickerLocale.pt_br,
minDateTime: DateTime.now(),
dateFormat: 'dd/MM/yyyy', onConfirm: (dateTime, selectedIndex) {
String birthDate = DateFormat('dd/MM/yyyy').format(dateTime);
scheduleStore.setDayIniController(birthDate);
scheduleStore.setDayIni(birthDate);
},
pickerTheme: DateTimePickerTheme(
pickerHeight: 110.0,
itemTextStyle: TextStyle(color: Colors.black87),
showTitle: true,
cancel: Text(
'Cancelar',
style: TextStyle(color: Colors.redAccent, fontSize: 18),
),
confirm: Text(
'Confirmar',
style: TextStyle(color: Colors.blueAccent, fontSize: 18),
),
));
}
void changeAlterHours(TextEditingController controller, Function function) {
DatePicker.showDatePicker(context,
locale: DateTimePickerLocale.pt_br,
maxDateTime: DateTime(2020, 1, 59, 2),
dateFormat: 'HH:mm',
pickerMode: DateTimePickerMode.time, onCancel: () {
controller.clear();
function(controller);
}, onConfirm: (dateTime, selectedIndex) {
String hour = DateFormat('HH:mm').format(dateTime);
controller.text = hour;
function(controller);
},
pickerTheme: DateTimePickerTheme(
cancelTextStyle: TextStyle(color: Colors.redAccent),
pickerHeight: 110.0,
itemTextStyle: TextStyle(color: Colors.black87),
showTitle: true,
cancel: Text(
'Limpar',
style: TextStyle(color: Colors.redAccent, fontSize: 18),
),
confirm: Text(
'Confirmar',
style: TextStyle(color: Colors.blueAccent, fontSize: 18),
),
));
}
@override
void dispose() {
disposer();
super.dispose();
}
}
I have other screens in which I’m only reusing all the logic to display the scaffold, but this specific does not work, below follows the code of MOBX:
@observable
bool enableScheduleSending = false;
@observable
bool enableScheduleOk = false;
@observable
bool enableScheduleError = false;
@action
Future<void> saveSchedule() async {
enableScheduleSending = true;
await Future.delayed(Duration(seconds: 2));
enableScheduleSending = false;
ScheduleEnableScheduleForm form = await createFormEnableSchedule();
await sendEnableSchedule(form);
}
@action
Future<void> sendEnableSchedule(ScheduleEnableScheduleForm form) async {
int response = 2;
if (response == 200) {
enableScheduleOk = true;
} else {
enableScheduleError = true;
}
await Future.delayed(Duration(seconds: 2));
enableScheduleOk = false;
enableScheduleError = false;
}
Just to facilitate posted a video showing what is happening: [1]: https://youtu.be/O-JgUDQxXjY
Are you having problems with the
showSnackBar
, it is used in widget Scaffold. I found nowhere the text displayed in the videoErro ao cadastrar
, but try to change the Reactions that are withindidChangeDependencies()
to theinitState()
– Matheus Ribeiro
I’m sorry, I just forgot to change here the message presented. My doubt is the
initState()
would be for when starts the screen, already thedidChangeDependencies()
would be more when there is some change, right? But anyway I will try to make these changes today.– Dieinimy Maganha