【问题标题】:Drawer body not updating after setState is called调用 setState 后抽屉主体未更新
【发布时间】:2019-04-09 18:06:43
【问题描述】:

我有一个用于显示抽屉的屏幕控制器。控制器作为参数传递到显示抽屉的主屏幕。抽屉主体应根据所选项目而变化。

class HomeScreen extends StatefulWidget {
  final HomeController controller;

  HomeScreen(this.controller);

  @override
  _HomeScreenState createState() => new _HomeScreenState(this.controller);
}

class _HomeScreenState extends State<HomeScreen>
    with SingleTickerProviderStateMixin {
  HomeController controller;
  TabController _tabController;

  _HomeScreenState(this.controller);

  @override
  void initState() {
    super.initState();
    _tabController =
        TabController(length: controller.tabItems.length, vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    switch (controller.getMenuType()) {
      case MenuType.drawer:
        return buildDrawer();
      case MenuType.tabbarbottom:
        return buildTopTabbar();
      case MenuType.tabbartop:
        return buildTopTabbar();
      default:
        return buildDrawer();
    }
  }

  Widget buildDrawer() {
    return Scaffold(
      appBar: AppBar(title: Text("test")),
      body: _buildDrawerBody(),
      drawer: Drawer(
        child: ListView(padding: EdgeInsets.zero, children: _getDrawerTiles()),
      ),
    );
  }

用户选择配置以显示标签栏或抽屉。在抽屉的情况下,问题是即使在调用 setState 并且抽屉主体函数正在创建一个具有正确页面的新小部件 Pagebuilder 之后,它也不会在屏幕上反映(或刷新)

Widget _buildDrawerBody() {
    Page page = controller.getSelectedPage();
    PageBuilderController pageController = PageBuilderController(page: page);
    return PageBuilder(pageController);
  }

  List<Widget> _getDrawerTiles() {
    Widget header = DrawerHeader(
      child: Text('Drawer Header'),
      decoration: BoxDecoration(
        color: Colors.blue,
      ),
    );
    List<Widget> tiles = controller.tabItems
        .map<Widget>((tab) => ListTile(
              title: Text(tab.label),
              onTap: () {
                // Update the state of the app
                // ...
                setState(() {
                  controller.selectedTab = tab;
                  Navigator.pop(context);
                });
              },
            ))
        .toList(growable: true);
    tiles.insert(0, header);
    return tiles;
  }

我已确保 getselectedpage 返回正确的结果

【问题讨论】:

  • 附注:你的State 实现应该有无参数的构造函数。要从State 访问小部件的最终字段,请使用widget 属性。例如。 widget.controller.tabItems.length
  • 你能创建一个最小的、完整的、可运行的例子吗?上面的部分代码不看HomeController的出处很难看懂。

标签: dart flutter


【解决方案1】:

我遇到的是,当您将小部件放在构建方法之外的方法中时,它们无法按预期工作。尝试在 build 方法中将 buildDrawer 和 _buildDrawerBody 声明为最终的 Widget,看看这是否会有所不同。

@override
Widget build(BuildContext context) {
  final Widget _buildDrawerBody = ...

  final Widget buildDrawer = Scaffold(
    appBar: AppBar(title: Text("test")),
    body: _buildDrawerBody,
    drawer: Drawer(
      child: ListView(padding: EdgeInsets.zero, children: _getDrawerTiles()),
    ),
  );

  switch (controller.getMenuType()) {
    case MenuType.drawer:
      return buildDrawer;
    case MenuType.tabbarbottom:
      return buildTopTabbar();
    case MenuType.tabbartop:
      return buildTopTabbar();
    default:
      return buildDrawer;
  }
}

这篇文章可能会提供一些关于创建小部件的最佳实践的见解:https://medium.com/flutter-io/out-of-depth-with-flutter-f683c29305a8

【讨论】:

    猜你喜欢
    • 2021-03-26
    • 2018-09-20
    • 1970-01-01
    • 2014-04-19
    • 2019-06-20
    • 1970-01-01
    • 2019-03-22
    • 1970-01-01
    • 2020-09-16
    相关资源
    最近更新 更多