导航到新的小部件后尝试访问InheritedWidget时遇到麻烦。
我有这样的顶层小部件
class App extends StatelessWidget{ build(context){ return MaterialApp( title: 'Iniciar Sesion', home: LoginBlocProvider(child: WelcomeScreen()), ); } }
然后,WelcomeScreen具有一个导航到LoginScreen的按钮
class WelcomeScreen extends StatelessWidget { @override Widget build(BuildContext context){ return Scaffold( body: Center(child: MyButton) ); } } class MyButton extends StatelessWidget { @override Widget build(BuildContext context) { return RaisedButton( shape: StadiumBorder(), child: Text('Ingresar', style: TextStyle(color: Colors.black)), elevation: 5.0, onPressed: () { Navigator.of(context).push(MaterialPageRoute( builder: (BuildContext context) =>LoginScreen() )); } ); } }
最后,在LoginScreen中,我想访问InheritedWidget
class LoginScreen extends StatefulWidget { @override _LoginScreenState createState() => _LoginScreenState(); } class _LoginScreenState extends State<LoginScreen> { LoginBloc bloc; @override void didChangeDependencies() { bloc = LoginBlocProvider.of(context); super.didChangeDependencies(); } @override Widget build(BuildContext context){ return Scaffold( body: Stack( fit: StackFit.expand, children: <Widget>[ Positioned( top: 0.0, child: Image.asset('assets/images/img.jpg', fit: BoxFit.none, ), ), _buildLogin(), ], ), ); } }
编辑: 这是LoginBlocProvider
class LoginBlocProvider extends InheritedWidget { final bloc; LoginBlocProvider({Key key, Widget child}) : bloc = LoginBloc(), super(key:key, child:child); @override bool updateShouldNotify(InheritedWidget oldWidget) => true; static LoginBloc of(BuildContext context) { return (context.inheritFromWidgetOfExactType(LoginBlocProvider) as LoginBlocProvider).bloc; } }
但是,当我运行InheritedWidget的.of方法时,出现此错误
I/flutter (27725): The following NoSuchMethodError was thrown building Builder: I/flutter (27725): The getter 'bloc' was called on null. I/flutter (27725): Receiver: null I/flutter (27725): Tried calling: bloc
我的印象是,这都与Navigator.push构建器方法中的上下文有关。因为如果使用没有Navigator.push的LoginScreen小部件,则可以很好地使用InheritedWidget
发生错误是因为传递给该LoginBlocProvider.of()方法的上下文找不到该实例。
LoginBlocProvider.of()
有什么想法吗?
在您提供的代码中,LoginScreen不是其后代的LoginBlocProvider原因就是它找不到祖先小部件。您的代码将WelcomeScreen路径包装在中LoginBlocProvider,而不是整个导航器中。解决方案是包装您MaterialApp的内容LoginBlocProvider,然后您将可以在应用程序中的任何地方访问它。
LoginScreen
LoginBlocProvider
WelcomeScreen
MaterialApp
class App extends StatelessWidget { @override Widget build(context) { return LoginBlocProvider( child: MaterialApp( title: 'Iniciar Sesion', home: WelcomeScreen(), ), ); } }