从导航抽屉调用时,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
   );
  }
}