收到错误无法在_InheritedProviderScope<Repository>Widget<NdefWriteModel?>上方找到正确的Provider

问题描述 投票:0回答:1

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import '../repository/repository.dart';
import 'about.dart';
import 'common/form_row.dart';
import 'ndef_format.dart';
import 'ndef_write.dart';
import 'ndef_write_lock.dart';
import 'tag_read.dart';

class App extends StatelessWidget {
  static Future<Widget> withDependency() async {
    final repo = await Repository.createInstance();
    return MultiProvider(
      providers: [
        Provider<Repository>.value(
          value: repo,
        ),
      ],
      child: App(),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: _Home(context: context),
      theme: _themeData(Brightness.light),
      darkTheme: _themeData(Brightness.dark),
    );
  }
}

class _Home extends StatelessWidget {
  final BuildContext context;

  const _Home({super.key, required this.context});
  @override
  Widget build(BuildContext context) {
    context = this.context;
    return Scaffold(
      appBar: AppBar(
        title: Text('NFC Manager'),
      ),
      body: ListView(
        padding: EdgeInsets.all(2),
        children: [
          FormSection(children: [
            FormRow(
              title: Text('Tag - Read'),
              trailing: Icon(Icons.chevron_right),
              onTap: () => Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => TagReadPage.withDependency(),
                  )),
            ),
            FormRow(
              title: Text('Ndef - Write'),
              trailing: Icon(Icons.chevron_right),
              onTap: () => Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => NdefWritePage.withDependency(),
                  )),
            ),
            FormRow(
              title: Text('Ndef - Write Lock'),
              trailing: Icon(Icons.chevron_right),
              onTap: () => Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => NdefWriteLockPage.withDependency(),
                  )),
            ),
            if (Platform.isAndroid)
              FormRow(
                title: Text('Ndef - Format'),
                trailing: Icon(Icons.chevron_right),
                onTap: () => Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => NdefFormatPage.withDependency(),
                    )),
              ),
          ]),
          FormSection(children: [
            FormRow(
              title: Text('About'),
              trailing: Icon(Icons.chevron_right),
              onTap: () => Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => AboutPage(),
                  )),
            ),
          ]),
        ],
      ),
    );
  }
}

ThemeData _themeData(Brightness brightness) {
  return ThemeData(
    brightness: brightness,
    // Matches app icon color.
    primarySwatch: MaterialColor(0xFF4D8CFE, <int, Color>{
      50: Color(0xFFEAF1FF),
      100: Color(0xFFCADDFF),
      200: Color(0xFFA6C6FF),
      300: Color(0xFF82AFFE),
      400: Color(0xFF689DFE),
      500: Color(0xFF4D8CFE),
      600: Color(0xFF4684FE),
      700: Color(0xFF3D79FE),
      800: Color(0xFF346FFE),
      900: Color(0xFF255CFD),
    }),
    appBarTheme: AppBarTheme(
      brightness: Brightness.dark,
    ),
    inputDecorationTheme: InputDecorationTheme(
      isDense: true,
      border: OutlineInputBorder(),
      contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 12),
      errorStyle: TextStyle(height: 0.75),
      helperStyle: TextStyle(height: 0.75),
    ),
    elevatedButtonTheme: ElevatedButtonThemeData(
        style: ElevatedButton.styleFrom(
      minimumSize: Size.fromHeight(40),
    )),
    scaffoldBackgroundColor:
        brightness == Brightness.dark ? Colors.black : null,
    cardColor:
        brightness == Brightness.dark ? Color.fromARGB(255, 28, 28, 30) : null,
    dialogTheme: DialogTheme(
      backgroundColor: brightness == Brightness.dark
          ? Color.fromARGB(255, 28, 28, 30)
          : null,
    ),
    highlightColor:
        brightness == Brightness.dark ? Color.fromARGB(255, 44, 44, 46) : null,
    splashFactory: NoSplash.splashFactory,
  );
}

导航到

NdefWritePage.withDependency()
时出现错误

The following ProviderNotFoundException was thrown building NdefWritePage(dirty):
Error: Could not find the correct Provider<Repository> above this _InheritedProviderScope<NdefWriteModel?> Widget

This happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:

- You added a new provider in your `main.dart` and performed a hot-reload.
  To fix, perform a hot-restart.

- The provider you are trying to read is in a different route.

  Providers are "scoped". So if you insert of provider inside a route, then
  other routes will not be able to access that provider.

- You used a `BuildContext` that is an ancestor of the provider you are trying to read.

  Make sure that _InheritedProviderScope<NdefWriteModel?> is under your MultiProvider/Provider<Repository>.
  This usually happens when you are creating a provider and trying to read it immediately.

文件中的

stream: Provider.of<NdefWriteModel>(context, listen: false).subscribe(),

  NdefWriteModel(this._repo);

  final Repository _repo;

  Stream<Iterable<WriteRecord>> subscribe() {
    return _repo.subscribeWriteRecordList();
  }

  Future<void> delete(WriteRecord record) {
    return _repo.deleteWriteRecord(record);
  }

  Future<String?> handleTag(
      NfcTag tag, Iterable<WriteRecord> recordList) async {
    final tech = Ndef.from(tag);

    if (tech == null) throw ('Tag is not ndef.');

    if (!tech.isWritable) throw ('Tag is not ndef writable.');

    try {
      final message = NdefMessage(recordList.map((e) => e.record).toList());
      await tech.write(message);
    } on PlatformException catch (e) {
      throw (e.message ?? 'Some error has occurred.');
    }

    return '[Ndef - Write] is completed.';
  }
}

class NdefWritePage extends StatelessWidget {
  static Widget withDependency() => ChangeNotifierProvider<NdefWriteModel>(
        create: (context) =>
            NdefWriteModel(Provider.of(context, listen: false)),
        child: NdefWritePage(),
      );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Ndef - Write'),
      ),
      body: StreamBuilder<Iterable<WriteRecord>>(
        stream: Provider.of<NdefWriteModel>(context, listen: false).subscribe(),
        builder: (context, ss) => ListView(
          padding: EdgeInsets.all(2),
          children: [
            FormSection(children: [
              FormRow(
                title: Text('Add Record'),
                trailing: Icon(Icons.chevron_right),
                onTap: () async {
                  final result = await showDialog<String>(
                    context: context,
                    builder: (context) => SimpleDialog(
                      title: Text('Record Types'),
                      children: [
                        SimpleDialogOption(
                          child: Text('Text'),
                          onPressed: () => Navigator.pop(context, 'text'),
                        ),
                        SimpleDialogOption(
                          child: Text('Uri'),
                          onPressed: () => Navigator.pop(context, 'uri'),
                        ),
                        SimpleDialogOption(
                          child: Text('Mime'),
                          onPressed: () => Navigator.pop(context, 'mime'),
                        ),
                        SimpleDialogOption(
                          child: Text('External'),
                          onPressed: () => Navigator.pop(context, 'external'),
                        ),
                      ],
                    ),
                  );
                  switch (result) {
                    case 'text':
                      Navigator.push(
                          context,
                          MaterialPageRoute(
                            fullscreenDialog: true,
                            builder: (context) => EditTextPage.withDependency(),
                          ));
                      break;
                    case 'uri':
                      Navigator.push(
                          context,
                          MaterialPageRoute(
                            fullscreenDialog: true,
                            builder: (context) => EditUriPage.withDependency(),
                          ));
                      break;
                    case 'mime':
                      Navigator.push(
                          context,
                          MaterialPageRoute(
                            fullscreenDialog: true,
                            builder: (context) => EditMimePage.withDependency(),
                          ));
                      break;
                    case 'external':
                      Navigator.push(
                          context,
                          MaterialPageRoute(
                            fullscreenDialog: true,
                            builder: (context) =>
                                EditExternalPage.withDependency(),
                          ));
                      break;
                    case null:
                      break;
                    default:
                      throw ('unsupported: result=$result');
                  }
                },
              ),
              FormRow(
                title: Text('Start Session',
                    style: TextStyle(
                      color: ss.data?.isNotEmpty != true
                          ? Theme.of(context).disabledColor
                          : Theme.of(context).colorScheme.primary,
                    )),
                onTap: ss.data?.isNotEmpty != true
                    ? null
                    : () => startSession(
                          context: context,
                          handleTag: (tag) => Provider.of<NdefWriteModel>(
                                  context,
                                  listen: false)
                              .handleTag(tag, ss.data!),
                        ),
              ),
            ]),
            if (ss.data?.isNotEmpty == true)
              FormSection(
                header: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Text('RECORDS'),
                    Text(
                        '${ss.data!.map((e) => e.record.byteLength).reduce((a, b) => a + b)} bytes'),
                  ],
                ),
                children: List.generate(ss.data!.length, (i) {
                  final record = ss.data!.elementAt(i);
                  return _WriteRecordFormRow(i, record);
                }),
              ),
          ],
        ),
      ),
    );
  }
}``` 

i went throught the solution proposed [use-provider-to-update-scaffold-from-a-second-screen](https://stackoverflow.com/questions/66480332/use-provider-to-update-scaffold-from-a-second-screen/66486075#66486075) but either i am not well using it or it's not more working?




[use-provider-to-update-scaffold-from-a-second-screen](https://stackoverflow.com/questions/66480332/use-provider-to-update-scaffold-from-a-second-screen/66486075#66486075)

I expected to get out of this error but unfortunately it's didn't work
flutter provider flutter-getx
1个回答
0
投票

我偶然发现了这个代码库的类似问题。确保在任何依赖于

ChangeNotifierProvider
的小部件之上声明
Provider

您使用的是

withDependency
方法,这是正确的方法,乍一看,我没有发现任何错误。但是,有时热重载不起作用,当我将导航从
NdefReadPage()
更改为
NdefWritePage.withDepenency()
时,我必须重建并重新部署应用程序,才能使其正常工作。

为什么在将 flutter 应用程序存储库导入为依赖项时会出现此错误?

© www.soinside.com 2019 - 2024. All rights reserved.