ListTile на главном экране не обновляется с помощью InheritedWidget - PullRequest
0 голосов
/ 05 апреля 2020

Я начинаю работать с flutter / dart и пытаюсь реализовать простое приложение для заметок, используя InheritedWidget и TextControllers, но когда я добавляю или редактирую некоторые заметки, они не обновляют главный экран. Я напечатал новый список заметок в консоли, и он обновляется с добавлением и редактированием, но не обновляется на главном экране, все еще показывая начальный список заметок ({'title': 'someTitle1', 'text': 'someText1'}, ...).

main.dart:

void main() => runApp(NoteInheritedWidget(
  MaterialApp(
    title: 'Notes App',
    home: HomeList(),
  ),
));

корпус лесов домашнего экрана:

List<Map<String, String>> get _notes => NoteInheritedWidget.of(context).notes;
...
body: ListView.builder(
    itemCount: _notes.length,
    itemBuilder: (context, index) {
      return Card(
        margin: EdgeInsets.symmetric(vertical: 5, horizontal: 7),
        child: ListTile(
          onTap: () {
            Navigator.push(context,
                MaterialPageRoute(builder: (context) => NotePage(noteMode: NoteMode.Editing, index: index))
            );
            print(_notes);
          },
          trailing: Icon(Icons.more_vert),
          title: _NoteTitle(_notes[index]['title']),
          subtitle: _NoteText(_notes[index]['text']),
        ),
      );
    },
  ),

Добавить / редактировать страницу заметок:

enum NoteMode {
  Adding,
  Editing
}

class NotePage extends StatefulWidget {

  final NoteMode noteMode;
  final int index;

  const NotePage ({this.noteMode, this.index});

  @override
  _NotePageState createState() => _NotePageState();
}

class _NotePageState extends State<NotePage> {

  final TextEditingController _titleController = TextEditingController();
  final TextEditingController _textController = TextEditingController();

  List<Map<String, String>> get _notes => NoteInheritedWidget.of(context).notes;

  @override
  void didChangeDependencies() {
    if (widget.noteMode == NoteMode.Editing) {
      _titleController.text = _notes[widget.index]['text'];
      _textController.text = _notes[widget.index]['title'];
    }
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          widget.noteMode == NoteMode.Adding ? 'Add Note' : 'Edit Note'
        ),
        centerTitle: true,
        backgroundColor: Colors.indigo[700],
      ),
      body: Padding(
        padding: const EdgeInsets.symmetric(vertical: 30, horizontal: 20),
        child: SingleChildScrollView(
          child: Column(
            children: <Widget>[
              TextField(
                controller: _titleController,
                decoration: InputDecoration(
                  hintText: 'Note Title',
                  border: OutlineInputBorder(),
                ),
              ),
              SizedBox(height: 20),
              TextField(
                controller: _textController,
                maxLines: 20,
                decoration: InputDecoration(
                  hintText: 'Note Text',
                  border: OutlineInputBorder(),
                ),
              ),
              SizedBox(height: 10),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: <Widget>[
                  _NoteButton(Icons.save, 'Save', () {
                    final title = _titleController.text;
                    final text = _textController.text;

                    if (widget.noteMode == NoteMode.Adding) {
                      _notes.add({'title': title, 'text': text});
                      print(_notes);
                    } else if (widget.noteMode == NoteMode.Editing) {
                      _notes[widget.index] = {'title': title, 'text': text};
                      print(_notes);
                    }
                    Navigator.pop(context);
                  }),
                  _NoteButton(Icons.clear, 'Discard', () {
                    Navigator.pop(context);
                  }),
                  if (widget.noteMode == NoteMode.Editing)
                    _NoteButton(Icons.delete, 'Delete', () {
                      _notes.removeAt(widget.index);
                      Navigator.pop(context);
                    }),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

InheritedWidget:

class NoteInheritedWidget extends InheritedWidget {

  final notes = [
    {'title': 'someTitle1', 'text': 'someText1'},
    {'title': 'someTitle2', 'text': 'someText2'},
    {'title': 'someTitle3', 'text': 'someText3'}
  ];

  NoteInheritedWidget(Widget child) : super(child: child);

  static NoteInheritedWidget of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<NoteInheritedWidget>();
  }

  @override
  bool updateShouldNotify(NoteInheritedWidget old) {
    return old.notes != notes;
  }
}

Главный экран после добавления заметки: Домашний экран

Список заметок, напечатанных в консоли после добавления заметки:

I/flutter (18079): [{title: someTitle1, text: someText1}, {title: someTitle2, text: someText2}, {title: someTitle3, text: someText3}, {title: NewAddNoteTitle, text: NewAddNoteText}]

Я использую Android Studio и реальное устройство вместо эмулятора. Я не могу найти ошибку, и если у вас есть другой способ сделать это «обновление», пожалуйста, покажите мне.

1 Ответ

0 голосов
/ 06 апреля 2020

Я нашел решение, используя метод onPressed как asyn c, а затем пустой setState, есть ли проблемы для кода, делающего это?

code:

child: ListTile(
          onTap: () async {
            await Navigator.push(context,
                MaterialPageRoute(builder: (context) => NotePage(noteMode: NoteMode.Editing, index: index))
            );
            setState(() {});
            print(_notes);
          },
...
   floatingActionButton: FloatingActionButton(
    onPressed: () async {
      await Navigator.push(context,
          MaterialPageRoute(builder: (context) => NotePage(noteMode: NoteMode.Adding))
      );
      setState(() {});
      print(_notes.length);
      print(_notes);
    },
...