Usuwanie elementu listy z poziomu innego widgetu

0

Update:

Udało mi się naprawić sytuację kiedy po usunięciu notatki w funkcji onDeleteBtnTap zamiast

Navigator.of(context).pushNamedAndRemoveUntil(notesRoute, (route) => false);

wracam do notesView za pomocą:

Navigator.of(context).pop();

Jest ktoś w stanie podpowiedzieć dlaczego tak się dzieje? Domyślam się że jest to może kwestia tego że używając pop() wracam do widgetu a używając pushNamedAndRemoveUntil() czyszczę stack i tworzony jest nowy widok. Czy w ogóle dobrze rozumiem różnicę między pop a pushNamed? Jeśli tak to dlaczego tworzenie nowego widgetu nie działa tak jak bym tego chciał?

Oryginalny post:

Mój problem najlepiej przedstawia film:

Usuwanie elementów listy przez trailing button działa, jednak przekazanie notatki w argumencie pushNamed do NewEditNote i później usunięcie go z bazy danych nie, ponieważ lista nie chce się załadować po powrotnej nawigacji.

Cały kod: https://github.com/rm46627/mynotes/blob/main/mynotes-flutter/lib/views/notes/notes_view.dart
Minimum kodu:
notes_view.dart (widok z listą) :

class NotesView extends StatelessWidget {
  const NotesView({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Notes"),
      ),
      body: Padding(
          padding: const EdgeInsets.all(8),
          child: Column(
            children: [
              Expanded(
                child: StreamBuilder(
                  stream: Repository.get().allNotes,
                  builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
                    switch (snapshot.connectionState) {
                      case ConnectionState.waiting:
                      case ConnectionState.active:
                        if (snapshot.hasData) {
                          final notes = snapshot.data as List<Note>;
                          return NotesListView(
                            notes: notes.reversed.toList(),
                            onDeleteNote: (note) async {
                              await Repository.get().removeNote(note);
                            },
                            onTap: (Note note) {
                              Navigator.of(context)
                                  .pushNamed(newEditNoteRoute, arguments: note);
                            },
                          );
                        } else {
                          return const CircularProgressIndicator();
                        }
                        break;
                      default:
                        return const CircularProgressIndicator();
                    }
                  },
                ),
              )
            ],
          )),
    );
  }
}

notes_list_view.dart

typedef NoteCallback = void Function(Note note);

class NotesListView extends StatelessWidget {
  final List<Note> notes;
  final NoteCallback onDeleteNote;
  final NoteCallback onTap;

  const NotesListView({
    Key? key,
    required this.notes,
    required this.onDeleteNote,
    required this.onTap,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: notes.length,
      itemBuilder: (context, index) {
        final note = notes[index];
        return ListTile(
          onTap: () {
            onTap(note);
          },
          title: Text(
            note.content,
            maxLines: 2,
            softWrap: true,
            overflow: TextOverflow.ellipsis,
          ),
          trailing: IconButton(
              onPressed: () async {
                final deleteChoice = await showDeleteDialog(context);
                if (deleteChoice) {
                  onDeleteNote(note);
                }
              },
              icon: const Icon(Icons.delete)),
        );
      },
    );
  }
}

new_edit_note.dart :


class NewEditNoteView extends StatefulWidget {
  const NewEditNoteView({Key? key}) : super(key: key);

  @override
  State<NewEditNoteView> createState() => _NewEditNoteViewState();
}

class _NewEditNoteViewState extends State<NewEditNoteView> {
  Note? _note;
  late final TextEditingController _textController;
  String _title = "New note";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(_title),
          actions: _note == null
              ? [
                  IconButton(
                    onPressed: () => onDeleteBtnTap(),
                    icon: const Icon(Icons.delete),
                  )
                ]
              : [],
        ),
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: FutureBuilder(
            future: createNewOrGetNote(context),
            builder: (context, snapshot) {
              switch (snapshot.connectionState) {
                case ConnectionState.done:
                  _setupTextControllerListener();
                  return TextField(
                    controller: _textController,
                    keyboardType: TextInputType.multiline,
                    maxLines: null,
                    decoration: const InputDecoration(hintText: 'Type your note...'),
                  );
                default:
                  return const CircularProgressIndicator();
              }
            },
          ),
        ));
  }

  void onDeleteBtnTap() async {
    final choice = await showDeleteDialog(context);
    if (choice) {
      Repository.get().removeNote(_note!);
      _note = null;
    }
    if (context.mounted) {
      Navigator.of(context).pushNamedAndRemoveUntil(notesRoute, (route) => false);
    }
  }

  void setNote(Note note) {
    ...
  }

  void setEditTitle() {
    ...
  }

  Future<Note> createNewOrGetNote(BuildContext context) async {
    ...
  }

  void _setupTextControllerListener() async {
    ...
  }

  void _textControllerListener() async {
    ...
  }

  @override
  void initState() {
    ...
  }

  @override
  void dispose() {
    ...
  }
  
}

0

Moim zdaniem dostajesz jakiś błąd z API/Repozytorium. W tym miejscu masz fajną mieszankę ifów i switchów, który prawdopodobnie zwraca ci CircularProgressIndicator(), ponieważ żaden z tych warunków nie jest true, albo hasData zwraca false, ponieważ repozytorium zwraca pustą listę.

switch (snapshot.connectionState) {
                      case ConnectionState.waiting:
                      case ConnectionState.active:
                        if (snapshot.hasData) {
                          final notes = snapshot.data as List<Note>;
                          return NotesListView(
                            notes: notes.reversed.toList(),
                            onDeleteNote: (note) async {
                              await Repository.get().removeNote(note);
                            },
                            onTap: (Note note) {
                              Navigator.of(context)
                                  .pushNamed(newEditNoteRoute, arguments: note);
                            },
                          );
                        } else {
                          return const CircularProgressIndicator();
                        }
                        break;
                      default:
                        return const CircularProgressIndicator();
                    }
                  },

Co ci konsola podczas debugówania pokazuje?

PS.
Skąd ty masz ten kod? Na pewno jest twój?

1 użytkowników online, w tym zalogowanych: 0, gości: 1