Как я могу обновить виджет NoteScreen заметок, когда я добавляю элемент в виджет AddNote?

# #firebase #flutter #hybrid-mobile-app #state-management

Вопрос:

В заданном состоянии я вызываю _notes, чтобы получить заметки из firebase для обновления.

Но когда я добавляю заметку в виджет AddNote и нажимаю кнопку сохранить, а затем возвращаюсь на рабочий стол NoteScreen, она не обновляется автоматически. Я должен провести пальцем вниз, чтобы обновить, а затем _notes снова вызывается, и данные обновляются.

И мне также нужна обратная связь по моему коду, я новичок, и мнение о методах чистого кода будет иметь большое значение.

 class NoteScreen extends StatefulWidget {
  static const routeName = '/noteScreen';

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

class _NoteScreenState extends State<NoteScreen> {
  Widget currentPage;
  String search;
  bool isLoading = false;

  Future<void> _notes() async {
    try {
      final authData = Provider.of<Auth>(context, listen: false);
      await Provider.of<NoteList>(context, listen: false)
          .fetchAndSetNotes(search, authData.userId);
      print('Note Screen FetchAndSetNotes');
    } catch (err) {
      print(err.toString());
    }
  }

  @override
  void initState() {
    _notes();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    final note = Provider.of<NoteList>(context);
    print(note.items.length);
    SystemChrome.setEnabledSystemUIOverlays([]);
    return Scaffold(
      resizeToAvoidBottomInset: false,
      body: Stack(alignment: Alignment.topCenter, children: <Widget>[
        Container(
            decoration: BoxDecoration(
                gradient: LinearGradient(
                    begin: Alignment.topLeft,
                    end: Alignment.bottomRight,
                    colors: [Colors.teal, Colors.purple])),
            child: Scaffold(
              backgroundColor: Colors.transparent,
              appBar: AppBar(
                  actions: [
                    IconButton(
                      icon: Icon(Icons.add),
                      onPressed: () {
                        Navigator.of(context).pushNamed(AddNote.routeName);
                      },
                    ),
                    IconButton(
                        icon: Icon(Icons.logout),
                        onPressed: () {
                          Provider.of<Auth>(context, listen: false).logout();
                        })
                  ],
                  title: Text(
                    'NoteApp',
                    style: TextStyle(fontSize: 20),
                  ),
                  elevation: 0.0,
                  backgroundColor: Colors.transparent),
              body: SingleChildScrollView(
                child: Column(children: [
                  Align(
                      alignment: Alignment.topCenter,
                      child: Container(
                        height: MediaQuery.of(context).size.height * 0.10,
                        width: MediaQuery.of(context).size.width,
                        child: FloatingSearchBar(
                          borderRadius: BorderRadius.all(Radius.circular(20)),
                          hint: 'Search',
                          actions: [],
                          onQueryChanged: (query) {
                            setState(() {
                              try {
                                search = query;
                              } catch (err) {
                                print(err.toString());
                              }

                              _notes();
                            });
                          },
                          builder: (context, transition) {
                            return ClipRRect();
                          },
                        ),
                      )),
                  Align(
                    alignment: Alignment.bottomCenter,
                    child: Container(
                      height: MediaQuery.of(context).size.height * 0.80,
                      width: MediaQuery.of(context).size.width,
                      child: FutureBuilder(
                        builder: (context, snapshot) =>
                            snapshot.connectionState == ConnectionState.waiting
                                ? CircularProgressIndicator()
                                : RefreshIndicator(
                                    onRefresh: () => _notes(),
                                    child: ListView.builder(
                                      padding: EdgeInsets.all(10),
                                      itemCount: note.items.length,
                                      itemBuilder: (context, i) => Column(
                                        children: [
                                          GestureDetector(
                                            onTap: () {
                                              Navigator.push(
                                                context,
                                                MaterialPageRoute(
                                                  builder: (context) =>
                                                      NoteDisplay(
                                                    noteItem: note.items[i],
                                                  ),
                                                ),
                                              );
                                            },
                                            child: note.items[i] != null
                                                ? Padding(
                                                    padding: EdgeInsets.all(5),
                                                    child: NoteItem(
                                                        note.items[i].content,
                                                        note.items[i].dateTime,
                                                        note.items[i].title,
                                                        note.items[i].id),
                                                  )
                                                : Container(
                                                    child: Center(
                                                      child: Text(
                                                          'No notes Available'),
                                                    ),
                                                  ),
                                          ),
                                        ],
                                      ),
                                    ),
                                  ),
                      ),
                    ),
                  ),
                ]),
              ),
            )),
      ]),
    );
  }
}

 

**Виджет AddNote **

 class AddNote extends StatefulWidget {
  static const routeName = '/addNotes';
  @override
  _AddNoteState createState() => _AddNoteState();
}

class _AddNoteState extends State<AddNote> {
  final _form = GlobalKey<FormState>();
  TextEditingController titleControler = new TextEditingController();

  var _newNotes = Notes(id: null, title: '', content: '', dateTime: '');

  Future<void> _saveNote() async {
    final isvalid = _form.currentState.validate();
    if (!isvalid) {
      return;
    }
    _form.currentState.save();
    Navigator.of(context).pop();

    try {
      await Provider.of<NoteList>(context, listen: false).addNotes(_newNotes);
      print('add_note');
    } catch (err) {
      print('add_note');
      print(err.toString());
    }
  }

  @override
  Widget build(BuildContext context) {
    final DateTime dateTime = DateTime.now();
    String formattedDate = DateFormat('yyyy-MM-dd – kk:mm').format(dateTime);
    Size size = MediaQuery.of(context).size;
    return Container(
      decoration: BoxDecoration(
          gradient: LinearGradient(
              begin: Alignment.topLeft,
              end: Alignment.bottomRight,
              colors: [Colors.teal, Colors.purple])),
      child: Scaffold(
        backgroundColor: Colors.transparent,
        appBar: AppBar(
          elevation: 0.0,
          backgroundColor: Colors.transparent,
          title: Text('Add notes '),
          actions: [IconButton(icon: Icon(Icons.save), onPressed: _saveNote)],
        ),
        body: Center(
          child: Form(
            key: _form,
            child: Container(
              height: size.height * 0.7,
              margin: EdgeInsets.all(20),
              decoration: BoxDecoration(
                  borderRadius: BorderRadius.all(Radius.circular(30))),
              child: Card(
                margin: EdgeInsets.all(30),
                elevation: 20,
                child: SingleChildScrollView(
                  child: Container(
                    padding: EdgeInsets.all(10),
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        TextFormField(
                          validator: (value) {
                            if (value.isEmpty) {
                              return 'Please enter a Title';
                            }
                            return null;
                          },
                          controller: titleControler,
                          decoration: InputDecoration(
                            hintText: 'Title',
                          ),
                          onSaved: (value) {
                            _newNotes = Notes(
                                title: value,
                                id: _newNotes.id,
                                content: _newNotes.content,
                                dateTime: formattedDate);
                            print(value.toString());
                          },
                          textInputAction: TextInputAction.next,
                        ),
                        SizedBox(
                          height: 20,
                        ),
                        TextFormField(
                          validator: (value) {
                            if (value.isEmpty) {
                              return "The content cannon't be empty";
                            }
                            return null;
                          },
                          onSaved: (value) {
                            _newNotes = Notes(
                                title: _newNotes.title,
                                content: value,
                                id: _newNotes.id,
                                dateTime: formattedDate);
                            print(value.toString());
                          },
                          maxLines: null,
                          keyboardType: TextInputType.multiline,
                          decoration: InputDecoration(hintText: 'Note content'),
                        ),
                        SizedBox(
                          height: 10,
                        ),
                        Text('$formattedDate')
                      ],
                    ),
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
 

Ответ №1:

Я верю, что то, чего мы хотим, — это поток, а не будущее. я не знаю, как выглядит ваша функция fetchAndSetNotes (), но вместо этого FirebaseFirestore.instance.collection(collectionName).doc(id).get() вы должны сделать Firestore.instance.collection("collectionName").doc(id).snapshots() то, что даст вам поток. вы используете StreamBuilder (учитывая, что вы используете поставщика, вы должны использовать поставщика потока) вместо FutureBuilder.