Warm tip: This article is reproduced from serverfault.com, please click

dart-Flutter Bloc:屈服状态不会触发小部件重建

(dart - Flutter bloc: yielding state doesn't triggers widget rebuild)

发布于 2020-11-27 23:32:50

在我的提醒应用程序中,当我单击“添加提醒”按钮时,它实际上将提醒添加到了数据库中,然后更新了我的提醒,但提醒列表并未重建。由于某些原因,当我删除提醒时,类似的情况也很好用。

我集团的一部分:


  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 _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);
            },
          );
        },
      );

状态:


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,
      ];
}

浪费了几天,想解决这个问题。有关更多详细信息,你可以在github上查看我的项目:https : //github.com/rockstar4095/reminder_flutter_app/tree/main_screen

Questioner
Yaro Best
Viewed
11
Taha Malik 2020-11-28 08:53:48

问题出在noterer_item.dart文件中,函数_reminderDescription中Flexible与非Flex父级一起使用只需删除Flexible Widget或使其成为Row或Column Widget的直接子代,一切都会正常进行。

  Widget _reminderDescription(BuildContext context) => Align(
    alignment: Alignment.centerLeft,
    child: RichText(
      overflow: TextOverflow.ellipsis,
      text: TextSpan(
        text: _current.description,
        style: Theme.of(context).textTheme.caption,
      ),
    ),
  );

同时也更新MainScreen Widget

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;
      }),
    );
  }

编辑

Navigator.of(context).pop()弹出对话框保存功能中也缺少你。

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();
        },
      );