简体   繁体   中英

Flutter : Could not find the correct Provider<EntryProvider> above this Page Widget

Getting a error when trying to run, but no specific things what I could fix Tried to example given by the error, but no luck. The error even says ask help from stackoverflow so here I am after trying to find help from google, but no luck.

Picture of the error

在此处输入图像描述

Why does my Provider break in this case?

Inside my page

  @override
  Widget build(BuildContext context) {
Widget build(BuildContext context) {
    ChangeNotifierProvider<EntryProvider>
      (
      create: (_)=>EntryProvider(),
      child:(MaterialWidget()),
    );
    final entryProvider = Provider.of<EntryProvider>(context);
    return Scaffold(
      appBar: AppBar(
        title: Text('My Journal'),
      ),
      body: StreamBuilder<List<Entry>>(
          stream: entryProvider.entries,
          builder: (context, snapshot) {
            return ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (context, index) {
                  return ListTile(
                    trailing:
                    Icon(Icons.edit, color: Theme.of(context).accentColor),
                    title: Text(
                      formatDate(DateTime.parse(snapshot.data[index].date),
                          [MM, ' ', d, ', ', yyyy]),
                    ),
                    onTap: () {
                      Navigator.of(context).push(MaterialPageRoute(
                          builder: (context) =>
                              EntryScreen(entry: snapshot.data[index])));
                    },
                  );
                });
          }),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {
          Navigator.of(context)
              .push(MaterialPageRoute(builder: (context) => EntryScreen()));
        },
      ),
    );
  }
}

Inside my provider

  final firestoreService = FirestoreService();
  DateTime _date;
  String _entry;
  String _entryId;
  var uuid = Uuid();

  //Getters
  DateTime get date => _date;
  String get entry => _entry;
  Stream<List<Entry>> get entries => firestoreService.getEntries();

  //Setters
  set changeDate(DateTime date){
    _date = date;
    notifyListeners();
  }

  set changeEntry(String entry){
    _entry = entry;
    notifyListeners();
  }

  //Functions
  loadAll(Entry entry){
    if (entry != null){
      _date = DateTime.parse(entry.date);
      _entry =entry.entry;
      _entryId = entry.entryId;
    } else {
      _date = DateTime.now();
      _entry = null;
      _entryId = null;
    }
  }

  saveEntry(){
    if (_entryId == null){
      //Add
      var newEntry = Entry(date: _date.toIso8601String(), entry: _entry, entryId: uuid.v1());
      print(newEntry.entry);
      firestoreService.setEntry(newEntry);
    } else {
      //Edit
      var updatedEntry = Entry(date: _date.toIso8601String(), entry: _entry, entryId: _entryId);
      firestoreService.setEntry(updatedEntry);
    }
  }

  removeEntry(String entryId){
    firestoreService.removeEntry(entryId);
  }

}```

class EntryScreen extends StatefulWidget {
  final Entry entry;

  EntryScreen({this.entry});

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

class _EntryScreenState extends State<EntryScreen> {

  final entryController = TextEditingController();

  @override
  void dispose() {
    entryController.dispose();
    super.dispose();
  }

  @override
  void initState() {
    final entryProvider = Provider.of<EntryProvider>(context,listen: false);
    if (widget.entry != null){
      //Edit
      entryController.text = widget.entry.entry;

      entryProvider.loadAll(widget.entry);
    } else {
      //Add
      entryProvider.loadAll(null);
    }
    super.initState();
  }


  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<EntryProvider>
    (
        create: (_)=>EntryProvider(),
        child: Scaffold(
          body: Consumer<EntryProvider>(
            builder: (context, entryProvider, child){
            return Scaffold(
              appBar: AppBar(title: Text(formatDate(entryProvider.date, [MM, ' ', d, ', ', yyyy])),
              actions: [

                IconButton(
                  icon: Icon(Icons.calendar_today),
                  onPressed: (){
                    _pickDate(context,entryProvider).then((value) {
                      if (value != null){
                        entryProvider.changeDate = value;
                      }
                    });
                  },
                )
                ],),
              body: Padding(
                padding: const EdgeInsets.all(8.0),
                child: ListView(
                  children: [
                    TextField(
                      decoration: InputDecoration(
                        labelText: 'Daily Entry', border: InputBorder.none,
                      ),
                      maxLines: 12,
                      minLines: 10,
                      onChanged: (String value) => entryProvider.changeEntry = value,
                      controller: entryController,
                    ),
                    RaisedButton(
                      color: Theme.of(context).accentColor,
                      child: Text('Save',style: TextStyle(color: Colors.white)),
                      onPressed: () {
                        entryProvider.saveEntry();
                        Navigator.of(context).pop();
                      },
                    ),
                    (widget.entry != null) ? RaisedButton(
                      color: Colors.red,
                      child: Text('Delete',style: TextStyle(color: Colors.white)),
                      onPressed: () {
                        entryProvider.removeEntry(widget.entry.entryId);
                        Navigator.of(context).pop();
                      },
                    ): Container(),
                  ],
                ),
              ),
            );
            }
          )
        )
    );
  }

   Future<DateTime> _pickDate(BuildContext context, EntryProvider entryProvider) async {
    final DateTime picked = await showDatePicker(
      context: context, initialDate: entryProvider.date, firstDate: DateTime(2019),
       lastDate: DateTime(2050));
    if (picked != null) return picked;
  }
}```

Did the same in my other file, but still getting the same error with that one

You need to create the ChangeNotifierProvider widget in the parent of your page so it can after get the Provider. Because now it tries to look for your provider and cannot find it in the tree.

ChangeNotifierProvider<EntryProvider>(
 create: (_) => EntryProvider(),
 child: YourPageWidget(),
)

Your example:

return ChangeNotifierProvider<EntryProvider>
      (
      create: (_)=>EntryProvider(),
      child: Scaffold(
        body: Consumer<EntryProvider>(
          builder: (context, entryProvider, child){
            return StreamBuilder<List<Entry>>(
                stream: entryProvider.entries,
                builder: (context, snapshot) {
                  return ListView.builder(
                      itemCount: snapshot.data.length,
                      itemBuilder: (context, index) {
                        return ListTile(
                          trailing:
                          Icon(Icons.edit, color: Theme.of(context).accentColor),
                          title: Text(
                            formatDate(DateTime.parse(snapshot.data[index].date),
                                [MM, ' ', d, ', ', yyyy]),
                          ),
                          onTap: () {
                            Navigator.of(context).push(MaterialPageRoute(
                                builder: (context) =>
                                    EntryScreen(entry: snapshot.data[index])));
                          },
                        );
                      });
                });
          },
        ),
      )
    );

Easier option, rather than trying to wrap the widgets was to wrap the main, so everything everywhere works

   @override
   Widget build(BuildContext context) {
   return MultiProvider(
    providers: [
      StreamProvider<NUser>.value(
        value: AuthService().user,
      ),
      ChangeNotifierProvider<EntryProvider>(
        create: (context) => EntryProvider(),
      )
    ],
    child: MaterialApp(
      home:Wrapper(),
    ),
        );```

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM