Как передать аргумент функции setState без MaterialPageRoute? - PullRequest
0 голосов
/ 27 февраля 2020

У меня проблема с обновлением состояния. Мне нужно передать функцию с setState в виджет, но я не знаю, как. Проблема в том, что мне нужно передать функцию stati c, и там я не могу выполнить 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;
    });
  }
}

1 Ответ

0 голосов
/ 28 февраля 2020

Ваша проблема в том, что вы пытаетесь заполнить screens при первом создании виджета, присвоив ему List объектов непосредственно в объявлении поля:

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

  ...
}

Когда вы заполняете объект следующим образом для этого вы можете использовать только поля и методы stati c. Это проблема для showMusicTabAndPlay, так как он вызывает setState, который является методом экземпляра и не может быть вызван из метода stati c.

Вместо этого вы должны заполнить screens внутри конструктор или метод initState (с последним рекомендуемым):

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

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

  ...
}

Теперь вы можете иметь showMusicTabAndPlay как метод экземпляра, а не как метод stati c, и ошибка будет go прочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...