从导航抽屉调用时,Flutter 有状态小部件未更新
Flutter stateful widget is not updating while calling from Navigation drawer
我正在尝试更新 class 的有状态小部件,同时从导航抽屉中调用它。无状态小部件在从导航抽屉中调用时正在更新。这是我调用 'Fragment First' 的导航抽屉。
class DrawerItem {
String title;
IconData icon;
DrawerItem(this.title, this.icon);
}
class HomePage extends StatefulWidget {
final drawerItems = [
new DrawerItem("First Fragment", Icons.rss_feed),
new DrawerItem("Second Fragment", Icons.local_pizza),
new DrawerItem("Third Fragment", Icons.info)
];
@override
State<StatefulWidget> createState() {
return new HomePageState();
}
}
class HomePageState extends State<HomePage> {
int _selectedDrawerIndex = 0;
_getDrawerItemWidget(int pos) {
switch (pos) {
case 0:
return new FirstFragmen(pos);
case 1:
return new FirstFragmen(pos);
case 2:
return new FirstFragmen(pos);
default:
return new Text("Error");
}
}
_onSelectItem(int index) {
setState(() => _selectedDrawerIndex = index);
Navigator.of(context).pop(); // close the drawer
}
@override
Widget build(BuildContext context) {
List<Widget> drawerOptions = [];
for (var i = 0; i < widget.drawerItems.length; i++) {
var d = widget.drawerItems[i];
drawerOptions.add(
new ListTile(
leading: new Icon(d.icon),
title: new Text(d.title),
selected: i == _selectedDrawerIndex,
onTap: () => _onSelectItem(i),
)
);
}
return new Scaffold(
appBar: new AppBar(
// here we display the title corresponding to the fragment
// you can instead choose to have a static title
title: new Text(widget.drawerItems[_selectedDrawerIndex].title),
),
drawer: new Drawer(
child: new Column(
children: <Widget>[
new UserAccountsDrawerHeader(
accountName: new Text("John Doe"), accountEmail: null),
new Column(children: drawerOptions)
],
),
),
body: _getDrawerItemWidget(_selectedDrawerIndex),
);
}
}
首先是片段:
class FirstFragment extends StatefulWidget {
int pos;
FirstFragment(this.pos);
@override
_FirstFragmentState createState() => new _FirstFragmentState(pos);
}
class _FirstFragmentState extends State<FirstFragment> {
int pos;
_FirstFragmentState(this.pos);
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Center(
child: new Text("Hello Fragment $pos"), >printing 'pos' only. It remains
> same all time when new class is called.
);
}
}
如果我使用的是无状态小部件,那么它会被更新,但有状态小部件不会被更新。我尝试使用断点进行调试,但 _FirstFragmentState class 仅被调用一次。有没有办法在第二次调用时重绘所有小部件。
状态创建一次,然后为小部件的多个实例共享。由于您在状态构造函数中采用 pos
,因此当小部件更改时它不会在稍后更新。
解决此问题的一种方法是删除 _FirstFragmentState
中的 pos
,并直接引用 FirstFragment
中的 pos
。您可以通过您所在州 class.
的 widget
字段访问它
class _FirstFragmentState extends State<FirstFragment> {
@override
Widget build(BuildContext context) {
return new Center(
child: new Text("Hello Fragment ${widget.pos}"), // -> use pos from FirstFragment
);
}
}
我正在尝试更新 class 的有状态小部件,同时从导航抽屉中调用它。无状态小部件在从导航抽屉中调用时正在更新。这是我调用 'Fragment First' 的导航抽屉。
class DrawerItem {
String title;
IconData icon;
DrawerItem(this.title, this.icon);
}
class HomePage extends StatefulWidget {
final drawerItems = [
new DrawerItem("First Fragment", Icons.rss_feed),
new DrawerItem("Second Fragment", Icons.local_pizza),
new DrawerItem("Third Fragment", Icons.info)
];
@override
State<StatefulWidget> createState() {
return new HomePageState();
}
}
class HomePageState extends State<HomePage> {
int _selectedDrawerIndex = 0;
_getDrawerItemWidget(int pos) {
switch (pos) {
case 0:
return new FirstFragmen(pos);
case 1:
return new FirstFragmen(pos);
case 2:
return new FirstFragmen(pos);
default:
return new Text("Error");
}
}
_onSelectItem(int index) {
setState(() => _selectedDrawerIndex = index);
Navigator.of(context).pop(); // close the drawer
}
@override
Widget build(BuildContext context) {
List<Widget> drawerOptions = [];
for (var i = 0; i < widget.drawerItems.length; i++) {
var d = widget.drawerItems[i];
drawerOptions.add(
new ListTile(
leading: new Icon(d.icon),
title: new Text(d.title),
selected: i == _selectedDrawerIndex,
onTap: () => _onSelectItem(i),
)
);
}
return new Scaffold(
appBar: new AppBar(
// here we display the title corresponding to the fragment
// you can instead choose to have a static title
title: new Text(widget.drawerItems[_selectedDrawerIndex].title),
),
drawer: new Drawer(
child: new Column(
children: <Widget>[
new UserAccountsDrawerHeader(
accountName: new Text("John Doe"), accountEmail: null),
new Column(children: drawerOptions)
],
),
),
body: _getDrawerItemWidget(_selectedDrawerIndex),
);
}
}
首先是片段:
class FirstFragment extends StatefulWidget {
int pos;
FirstFragment(this.pos);
@override
_FirstFragmentState createState() => new _FirstFragmentState(pos);
}
class _FirstFragmentState extends State<FirstFragment> {
int pos;
_FirstFragmentState(this.pos);
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Center(
child: new Text("Hello Fragment $pos"), >printing 'pos' only. It remains
> same all time when new class is called.
);
}
}
如果我使用的是无状态小部件,那么它会被更新,但有状态小部件不会被更新。我尝试使用断点进行调试,但 _FirstFragmentState class 仅被调用一次。有没有办法在第二次调用时重绘所有小部件。
状态创建一次,然后为小部件的多个实例共享。由于您在状态构造函数中采用 pos
,因此当小部件更改时它不会在稍后更新。
解决此问题的一种方法是删除 _FirstFragmentState
中的 pos
,并直接引用 FirstFragment
中的 pos
。您可以通过您所在州 class.
widget
字段访问它
class _FirstFragmentState extends State<FirstFragment> {
@override
Widget build(BuildContext context) {
return new Center(
child: new Text("Hello Fragment ${widget.pos}"), // -> use pos from FirstFragment
);
}
}