【问题标题】:How to pass argument function setState without MaterialPageRoute?如何在没有 MaterialPageRoute 的情况下传递参数函数 setState?
【发布时间】:2020-02-27 20:42:46
【问题描述】:

我有更新状态的问题。我需要将带有setState 的函数传递给小部件,但我不知道如何操作。问题是我需要传递一个静态函数,而在那里我不能执行setState。我必须解决哪些选项?

我的代码

class NavigationBar extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _NavigationBarState();
  }
}

class _NavigationBarState extends State<NavigationBar> {
  bool showMusicTab = false;
  bool openMusicTab = false;
  int index = 4;
  final List<Widget> screens = [
    Home(),
    Search(),
    AddPost(),
    Notifications(),
    Profile(showMusicTabAndPlay)
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: screens[index],
      persistentFooterButtons: showMusicTab
          ? <Widget>[
              Container(
                color: Colors.black,
                height: 20,
                width: MediaQuery.of(context).size.width,
                child: ListTile(
                  leading: Icon(Icons.favorite_border, color: Colors.white),
                  title: Center(
                    child: InkWell(
                      onTap: () {},
                      child: Text(
                        'Break my soul',
                        style: TextStyle(
                            color: Colors.white,
                            fontFamily: kRobotoBold,
                            fontWeight: FontWeight.bold),
                      ),
                    ),
                  ),
                  trailing: Icon(
                    Icons.pause_circle_filled,
                    color: Colors.white,
                  ),
                ),
              )
            ]
          : null,
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: index,
        onTap: (int index) {
          setState(() {
            this.index = index;
          });
        },
        type: BottomNavigationBarType.fixed,
        showSelectedLabels: false,
        showUnselectedLabels: false,
        backgroundColor: Colors.black,
        items: [
          new BottomNavigationBarItem(
            icon: new Icon(
              Icons.home,
              color: index == 0 ? Colors.pinkAccent : Colors.white,
            ),
            title: new Text('Home'),
          ),
          new BottomNavigationBarItem(
            icon: new Icon(
              Icons.search,
              color: index == 1 ? Colors.pinkAccent : Colors.white,
            ),
            title: new Text('Search'),
          ),
          new BottomNavigationBarItem(
            icon: new Icon(
              Icons.add_circle,
              color: index == 2 ? Colors.pinkAccent : Colors.white,
            ),
            title: new Text('Add post'),
          ),
          new BottomNavigationBarItem(
            icon: new Icon(
              Icons.notifications,
              color: index == 3 ? Colors.pinkAccent : Colors.white,
            ),
            title: new Text('Notifications'),
          ),
          new BottomNavigationBarItem(
              icon: Icon(
                Icons.person,
                color: index == 4 ? Colors.pinkAccent : Colors.white,
              ),
              title: Text('Profile'))
        ],
      ),
    );
  }

  static void showMusicTabAndPlay() {
    setState(() {
      showMusicTab = true;
    });
  }
}

【问题讨论】:

  • setState 不能在静态函数中使用,你为什么首先在静态函数中使用它??
  • @AhmedKhattab 我知道我想问什么,我问的是如何将带有setState 的函数传递给小部件,因为当我传递没有static 的函数时抱怨只通过静态函数
  • 您正在创建小部件列表作为字段声明的一部分,此时您只能使用静态值,因为实例值尚不存在。您应该改为在 initState 期间填充 screens。 (不幸的是,这意味着您将无法做到final [还]。)
  • @Abion47 填充screens 是什么意思?

标签: flutter dart flutter-layout


【解决方案1】:

您的问题是您试图在第一次创建小部件时填充screens,方法是直接在字段声明处为其分配对象的List

class _NavigationBarState extends State<NavigationBar> {
  final List<Widget> screens = [
    Home(),
    Search(),
    AddPost(),
    Notifications(),
    Profile(showMusicTabAndPlay)
  ];

  ...
}

当你像这样填充对象时,你只能使用静态字段和方法来填充它。这是showMusicTabAndPlay 的问题,因为它调用setState,这是一个实例方法,不能从静态方法调用。

相反,您应该在构造函数或initState 方法中填充screens(推荐使用后者):

class _NavigationBarState extends State<NavigationBar> {
  List<Widget> screens;

  @override
  void initState() {
    super.initState();
    screens = [
      Home(),
      Search(),
      AddPost(),
      Notifications(),
      Profile(showMusicTabAndPlay)
    ];
  }

  ...
}

有了这个,您现在可以让showMusicTabAndPlay 成为实例方法而不是静态方法,错误就会消失。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-10
    • 1970-01-01
    • 2013-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多