简体   繁体   中英

Error: Could not find the correct Provider<Provider2> above this Onboarding Widget

Here's my main.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:formvalidation/src/bloc/provider2.dart';
import 'package:formvalidation/src/onboarding/onboarding.dart';
import 'package:formvalidation/src/providers/color_provider.dart';
import 'package:formvalidation/src/pages/login_page.dart';
//import 'package:formvalidation/src/pages/producto_page.dart';
import 'package:formvalidation/src/pages/registro_page.dart';
import 'package:formvalidation/src/preferencias_usuario/preferencias_usuario.dart';
import 'package:formvalidation/fitness_app/fitness_app_home_screen.dart';

void main() async {
WidgetsFlutterBinding.ensureInitialized();

final prefs = new PreferenciasUsuario();
  await prefs.initPrefs();

  runApp(MyApp());

}


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    create: (_)=> Provider2();
    final prefs = new PreferenciasUsuario();
    print( prefs.token );

    return Provider2(
      child: MaterialApp(

        debugShowCheckedModeBanner: false,
        title: 'App4WOD',

        initialRoute: 'onboarding',
        routes: {

          'onboarding'  : ( BuildContext context ) => Onboarding(),
          'login'       : ( BuildContext context ) => LoginPage(),
          'registro'    : ( BuildContext context ) => RegistroPage(),
          'home'        : ( BuildContext context ) => FitnessAppHomeScreen(),          
        },
        theme: ThemeData( primaryColor: Colors.red,),
      ),
    );

  }
}

class HexColor extends Color {
  HexColor(final String hexColor) : super(_getColorFromHex(hexColor));

  static int _getColorFromHex(String hexColor) {
    hexColor = hexColor.toUpperCase().replaceAll('#', '');
    if (hexColor.length == 6) {
      hexColor = 'FF' + hexColor;
    }
    return int.parse(hexColor, radix: 16);
  }
}


}

And My Provider2

import 'package:flutter/material.dart';

import 'package:formvalidation/src/bloc/login_bloc.dart';
export 'package:formvalidation/src/bloc/login_bloc.dart';

import 'package:formvalidation/src/bloc/productos_bloc.dart';
export 'package:formvalidation/src/bloc/productos_bloc.dart';

import 'package:flutter/material.dart';

import 'package:formvalidation/src/onboarding/data/onboard_page_data.dart';


//class Provider2 extends InheritedWidget with ChangeNotifier {
class Provider2 extends InheritedWidget {  

  final loginBloc      = new LoginBloc();
  final _productosBloc = new ProductosBloc();


  static Provider2 _instancia;

  factory Provider2({ Key key, Widget child }) {

    if ( _instancia == null ) {
      _instancia = new Provider2._internal(key: key, child: child );
    }

    return _instancia;

  }

  Provider2._internal({ Key key, Widget child })
    : super(key: key, child: child );




  // Provider({ Key key, Widget child })
  //   : super(key: key, child: child );


  @override
  bool updateShouldNotify(InheritedWidget oldWidget) => true;


  static LoginBloc of ( BuildContext context ) {
    //return (context.dependOnInheritedWidgetOfExactType() as Provider).loginBloc; //ERROR AL LLAMAR METODO NO DEPRECADO
    return ( context.inheritFromWidgetOfExactType(Provider2) as Provider2 ).loginBloc;
  }

  static ProductosBloc productosBloc ( BuildContext context ) {
   // return (context.dependOnInheritedWidgetOfExactType() as Provider)._productosBloc;
    return ( context.inheritFromWidgetOfExactType(Provider2) as Provider2 )._productosBloc;
  }


  Color _color = onboardData[0].accentColor;

  Color get color => _color;

  set color(Color color) {
    _color = color;
    //notifyListeners();

}

}

The Error Is:

[38;5;248m════════ Exception caught by widgets library ═══════════════════════════════════[39;49m [38;5;244mThe following ProviderNotFoundException was thrown building Onboarding(dirty):[39;49m Error: Could not find the correct Provider above this Onboarding Widget

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

  • 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 Onboarding is under your MultiProvider/Provider. This usually happen when you are creating a provider and trying to read it immediatly.

    For example, instead of:

Widget build(BuildContext context) {
  return Provider<Example>(
    create: (_) => Example(),
    // Will throw a ProviderNotFoundError, because `context` is associated
    // to the widget that is the parent of `Provider<Example>`
    child: Text(context.watch<Example>()),
  ),
}

consider using builder like so:

Widget build(BuildContext context) {
  return Provider<Example>(
    create: (_) => Example(),
    // we use `builder` to obtain a new `BuildContext` that has access to the provider
    builer: (context) {
      // No longer throws
      return Text(context.watch<Example>()),
    }
  ),
}

If none of these solutions work, consider asking for help on StackOverflow: https://stackoverflow.com/questions/tagged/flutter

It looks like your MyApp is missing a widget responsible for creating the provider. Have you tried:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Provider<Provider2>(
    create: (_) => Provider2();
    builder: (context) {
      final prefs = new PreferenciasUsuario();
      print( prefs.token );

      return MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'App4WOD',
        initialRoute: 'onboarding',
        routes: {
          'onboarding'  : ( BuildContext context ) => Onboarding(),
          'login'       : ( BuildContext context ) => LoginPage(),
          'registro'    : ( BuildContext context ) => RegistroPage(),
          'home'        : ( BuildContext context ) => FitnessAppHomeScreen(),          
        },
        theme: ThemeData( primaryColor: Colors.red,),
      );
    });
  }
}

You can then call context.watch<Provider2>() or context.read<Provider2>() when you need to access something inside the provider in your app.

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