In my reminder app, when I click the add reminder button, it actually adds the reminder to the database and then updates my reminders, but the list of reminders is not rebuild. For some reason, a similar scenario works great when I delete my reminders.
part of my bloc:
void _loadReminders() async {
final reminders = await _repository.getAllReminders();
reminders.sort((a, b) => a.dateTime.isAfter(b.dateTime) ? 1 : -1);
if (reminders.isNotEmpty) {
add(RemindersLoaded(reminders: reminders));
}
}
@override
Stream<MainState> mapEventToState(MainEvent event) async* {
if (event is ItemSelected) {
yield state.copyWith(isSelectedModeActive: true);
} else if (event is SelectModeDisabled) {
yield state.copyWith(isSelectedModeActive: false);
} else if (event is RemindersLoaded) {
yield state.copyWith(reminders: event.reminders);
} else if (event is SaveReminderPressed) {
await _saveReminder(event.reminder);
_loadReminders();
} else if (event is DeletePressed) {
await deleteReminders();
_loadReminders();
add(SelectModeDisabled());
}
}
widget:
Widget _remindersList(BuildContext context) =>
BlocBuilder<MainBloc, MainState>(
builder: (context, state) {
return ListView.builder(
itemCount: state.reminders.length,
itemBuilder: (context, index) {
return ReminderItem(reminders: state.reminders, index: index);
},
);
},
);
state:
class MainState extends Equatable {
final bool isSelectedModeActive;
final List<Reminder> reminders;
final int quantityOfSelectedItems;
MainState({
this.isSelectedModeActive = false,
this.reminders,
}) : quantityOfSelectedItems =
reminders.where((reminder) => reminder.isSelected).length;
MainState copyWith({
bool isSelectedModeActive,
List<Reminder> reminders,
}) =>
MainState(
isSelectedModeActive: isSelectedModeActive ?? this.isSelectedModeActive,
reminders: List<Reminder>()..addAll(reminders ?? this.reminders),
);
@override
List<Object> get props => [
isSelectedModeActive,
reminders,
quantityOfSelectedItems,
];
}
wasted several days, trying to solve this. For more detail you can check my project on github: https://github.com/rockstar4095/reminder_flutter_app/tree/main_screen
The problem is here in reminder_item.dart file, in function _reminderDescription your are using Flexible
with non Flex parent. Just remove the Flexible Widget or make it direct child of Row or Column Widget and everything will work fine.
Widget _reminderDescription(BuildContext context) => Align( alignment: Alignment.centerLeft, child: RichText( overflow: TextOverflow.ellipsis, text: TextSpan( text: _current.description, style: Theme.of(context).textTheme.caption, ), ), );
Also update MainScreen Widget as well
class MainScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final content = Scaffold(
appBar: AppBar(
title: Text('Напоминания'),
actions: [
_deleteIcon(context),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
EditReminderDialog.open(context);
},
child: Icon(Icons.add),
),
body: _remindersList(context),
);
return BlocProvider(
create: (context) {
return context.read<MainBloc>();
},
child: Builder(builder: (context) {
return content;
}),
);
}
You are missing Navigator.of(context).pop()
as well in your popup dialog save function.
Widget _save(BuildContext context) => RaisedButton(
child: Text('Сохранить'),
onPressed: () {
final reminder = Reminder(
id: null,
title: 'test reminder title',
description:
'test reminder description ${DateTime.now().toLocal()}',
dateTime: DateTime.now(),
);
context.read<MainBloc>().add(SaveReminderPressed(reminder: reminder));
Navigator.of(context).pop();
},
);
Unfortunately, this doesn't works for me, it doesn't solves my problem.
I just ran your code, and it was the problem
thanks for pointing out this problem, but list with reminders still doesn't rebuilds after save reminder operation.
And yeah one more thing you create two blocs in your widget tree, one in main.dart file in AppBlocProvider class and the other one in main_screen.dart file
Check my updated code