导航到新窗口小部件后,我在尝试访问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()方法的上下文未找到实例.
有什么想法吗?
解决方法
在您提供的代码中,LoginScreen不是LoginBlocProvider的后代,这就是它无法找到祖先小部件的原因.您的代码在LoginBlocProvider中包装WelcomeScreen路由,但不包括整个导航器.解决方案是将您的MaterialApp包装在LoginBlocProvider中,然后您可以在应用程序的任何位置访问它.
class App extends StatelessWidget { @override Widget build(context) { return LoginBlocProvider( child: MaterialApp( title: 'Iniciar Sesion',home: WelcomeScreen(),); } }