从Navigation抽屉调用时,Flutter有状态窗口小部件不会更新

时间:2018-06-07 13:32:19

标签: flutter stateful

我正在尝试更新我的类的有状态小部件,同时从导航抽屉调用它。从Navigation Drawer调用无状态小部件时,它们正在更新。这是我的导航抽屉,我称之为'片段优先'。

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),
   );
    }
 }

这是Fragment First:

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类只调用一次。有没有办法在第二次调用时重绘所有小部件。

1 个答案:

答案 0 :(得分:1)

状态创建一次,然后为您的窗口小部件的多个实例共享。由于您在状态构造函数中使用pos,因此稍后在窗口小部件更改时不会更新它。

解决此问题的一种方法是删除pos中的_FirstFragmentState,并直接引用pos中的FirstFragment。您可以通过州级的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
   );
  }
}