所以我有一个继承的小部件,看起来像:
class InheritedStateWidget extends StatefulWidget { final Widget child; InheritedStateWidget({ @required this.child }); @override InheritedStateWidgetState createState() => new InheritedStateWidgetState(); static of(BuildContext context) { return (context.inheritFromWidgetOfExactType(_MyInheritedWidget) as _MyInheritedWidget).data; } } class InheritedStateWidgetState extends State<InheritedStateWidget> { String _userName; // Getter methods String get tasks => _userName; void changeUserName(String name) { setState(() { _userName = name; }); } @override Widget build(BuildContext context) { return new _MyInheritedWidget( data: this, child: widget.child, ); } } class _MyInheritedWidget extends InheritedWidget { final InheritedStateWidgetState data; _MyInheritedWidget({ Key key, this.data, Widget child}): super(key: key, child: child); @override bool updateShouldNotify(_MyInheritedWidget old) { return true; } }
和这样的main.dart:
void main() => runApp(InheritedStateWidget( child: new Builder ( builder: (context) => new MyApp())) ); class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return new MaterialApp( title: 'App One', theme: new ThemeData( primarySwatch: Colors.blue, ), home: new MyHomePage(), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key}) : super(key: key); @override _MyHomePageState createState() => new _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { final PageStorageBucket bucket = PageStorageBucket(); int currentTab; Widget currentPage; List<Widget> pages; HomePage one; ProfilePage two; @override void initState() { super.initState(); one = HomePage( key: exploreKey, ); two = Profile( key: myTasksKey, ); pages = [one, two]; currentPage = one; } @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar(title: new Text("Testing"),), body: new PageStorage( bucket: bucket, child: currentPage, ), bottomNavigationBar: BottomNavigationBar( currentIndex: currentTab, onTap: (int index) { setState(() { currentTab = index; currentPage = pages[index]; }); }, type: BottomNavigationBarType.fixed, items: <BottomNavigationBarItem> [ BottomNavigationBarItem( title: Text("Home"), icon: null ), BottomNavigationBarItem( title: Text("Profile"), icon: null ) ], ) ); } }
从我从一些指南中获得的信息,这就是我应该如何将继承的小部件传递到我的Material App及其所有路线,但是它似乎并没有将继承的小部件传递通过支架。从脚手架本身看来,我能够做类似的事情:
InheritedStateWidget.of(上下文)
它会成功地带回我的Inherited Widget,但是在currentPage Widget中,即HomePage(Stateful Widget)。我似乎无法访问它,我得到了
未处理的异常:NoSuchMethodError:类’HomePageState’没有实例获取方法’InheritedStateWidget’。接收方:“ HomePageState”的实例
我要去哪里错了?
我对您的前几节课进行了稍微的重组:
import 'package:flutter/material.dart'; void main() => runApp(InheritedStateWidget()); class InheritedStateWidget extends StatefulWidget { @override InheritedStateWidgetState createState() => InheritedStateWidgetState(); } class InheritedStateWidgetState extends State<InheritedStateWidget> { String _userName; // Getter methods String get tasks => _userName; void changeUserName(String name) { setState(() { _userName = name; }); } @override Widget build(BuildContext context) { return new MyInheritedWidget( data: this, child: MyApp(), ); } } class MyInheritedWidget extends InheritedWidget { final InheritedStateWidgetState data; MyInheritedWidget({Key key, this.data, Widget child}) : super(key: key, child: child); static MyInheritedWidget of(BuildContext context) => context.inheritFromWidgetOfExactType(MyInheritedWidget); @override bool updateShouldNotify(MyInheritedWidget old) => true; } class MyApp extends StatelessWidget { // in MyApp and below you can refer to MyInheritedWidget.of(context).data @override Widget build(BuildContext context) { return new MaterialApp( title: 'App One', home: new MyHomePage(), ); } }
我喜欢像这样加强State和InheritedWidget之间的接口,但这只是一个建议…
void main() => runApp(new Controller()); class Controller extends StatefulWidget { @override State<StatefulWidget> createState() => ControllerState(); } typedef void VoidIntFunction(int i); class ControllerState extends State<Controller> { String someString = ''; void someFunction(int v) { print('function called with $v'); } @override Widget build(BuildContext context) { return StateContainer( someString: someString, someFunction: someFunction, child: new ExampleApp(), ); } } class StateContainer extends InheritedWidget { final String someString; final VoidIntFunction someFunction; const StateContainer({ this.someString, this.someFunction, Widget child, }) : super(child: child); static StateContainer of(BuildContext context) => context.inheritFromWidgetOfExactType(StateContainer); @override bool updateShouldNotify(StateContainer oldWidget) => true; }
现在使用InheritedWidget的任何子级都具有对状态(someString)的读取权限,并且必须通过调用方法(someFunction)对其进行修改。涉及更多样板。
someString
someFunction