简体   繁体   English

Flutter:按下时如何更改 BottomNavBar 中的 FloatingactionButton 图标?

[英]Flutter: How to change the FloatingactionButton icon in the BottomNavBar when pressed?

I'm trying to change the icon of the FloatingActionButton() in the bottom navigation bar when clicked.单击时,我试图更改底部导航栏中 FloatingActionButton() 的图标。 It works fine but only when I leave the screen and come back?它工作正常但只有当我离开屏幕然后回来时? Does anyone know what's wrong?有谁知道怎么了? Setstate in the changeIcon() is called which should force a rerendering, or am I wrong? changeIcon() 中的 Setstate 被调用,这应该强制重新渲染,还是我错了?

I would really appreciate some help:)我真的很感激一些帮助:)

Edit: It doesnt even work if I put in the if this.pressed bool statement as child.编辑:如果我将 if this.pressed bool 语句作为子语句放入,它甚至不起作用。 The state of the this.pressed flag is changed from false to true (printed the state) but even this does not lead the button to change its icon. this.pressed标志的 state 从 false 更改为 true(打印状态),但即使这样也不会导致按钮更改其图标。

     return FloatingActionButton(
            child: this.pressed ? Icon(Icons.people) : Icon(Icons.close),
            onPressed: () {
              changeIcon();
            }); 

The code is attached here:代码附在这里:

class HomeState extends State<Home> {
  MapRadials buttonProvider;
  Icon fabIcon = Icon(Icons.perm_media);
  FloatingActionButton floatingActionButton;
  int _currentIndex = 0;
  List<Widget> _screens = [
    FeedScreen(),
    MapScreen(),
    MapScreen(),
    NotificationScreen(),
    ChatScreen(),
  ];

  @override
  void initState() {
    super.initState();
    floatingActionButton = FloatingActionButton(
      onPressed: () {},
      child: fabIcon,
    );
  }

  void changeIcon(Icon icon) {
    setState(() {
      fabIcon = icon;
    });
  }

  @override
  Widget build(BuildContext context) {
    final MapRadials radialProvider = Provider.of<MapRadials>(context);
    this.buttonProvider = radialProvider;

    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.white,
        leading: IconButton(
          icon: Icon(
            Icons.menu,
            size: 30.0,
            color: Colors.black,
          ),
          onPressed: () {},
        ),
        actions: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Row(
                children: <Widget>[
                  IconButton(
                    icon: Icon(
                      Icons.filter_list,
                      size: 30.0,
                      color: Colors.black,
                    ),
                    onPressed: () {},
                  ),
                  IconButton(
                    icon: Icon(
                      Icons.search,
                      size: 30.0,
                      color: Colors.black,
                    ),
                    onPressed: () {},
                  ),
                ],
              )
            ],
          )
        ],
      ),
      bottomNavigationBar: bottomNavBar(),
      floatingActionButton: this.floatingActionButton,
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
      body: _screens[_currentIndex],
    );
  }

  void onTabTapped(int index) {
    setState(() {
      if (index != 2) {
        _currentIndex = index;
        floatingActionButton = getFloatingActionButton(index);
      }
    });
  }

  Widget getFloatingActionButton(int index) {
    switch (index) {
      case 0: // Home
        return FloatingActionButton(child: Icon(Icons.add), onPressed: () {});
      case 1: // Map
        return FloatingActionButton(
            child: fabIcon,
            onPressed: () {
              changeIcon(Icon(Icons.save));
            });
      case 2: // Notification
        return FloatingActionButton(
            child: Icon(Icons.clear_all), onPressed: () {});
      case 3: // Chat
        return FloatingActionButton(
            child: Icon(Icons.add_comment), onPressed: () {});
      default:
        return FloatingActionButton(child: Icon(Icons.add), onPressed: () {});
    }
  }

  Widget bottomNavBar() {
    return BottomNavigationBar(
      type: BottomNavigationBarType.fixed,
      onTap: onTabTapped,
      currentIndex: _currentIndex,
      showSelectedLabels: false,
      showUnselectedLabels: false,
      items: [
        BottomNavigationBarItem(
          icon: Icon(
            Icons.home,
            color: Colors.black,
          ),
          title: Text('Feed'),
        ),
        BottomNavigationBarItem(
            icon: Icon(
              Icons.person_pin_circle,
              color: Colors.black,
            ),
            title: Text('Map')),
        BottomNavigationBarItem(
            icon: Icon(
              null,
            ),
            title: Text('Placeholder')),
        BottomNavigationBarItem(
          icon: Icon(
            Icons.notifications,
            color: Colors.black,
          ),
          title: Text('Noftications'),
        ),
        BottomNavigationBarItem(
            icon: Icon(
              Icons.chat_bubble,
              color: Colors.black,
            ),
            title: Text('Chat'))
      ],
    );
  }
}

You are changing the icon in the state and using setState() for it, and that is fine, but notice that setState() is rebuilding your widget tree with a Scaffold whose floatingActionButton parameter is floatingActionButton: this.floatingActionButton , and you are setting your this.floatingActionButton in the initState() method, that will be called only once (whenever the whole Widget is instantiated).您正在更改 state 中的图标并为其使用setState() ,这很好,但请注意setState()正在使用其floatingActionButton参数为floatingActionButton: this.floatingActionButtonScaffold重建您的小部件树,并且您正在设置您的this.floatingActionButton initState()方法中的 this.floatingActionButton,它只会被调用一次(每当实例化整个 Widget 时)。 Since that this.floatingActionButton is only being instantiated once with the initial icon, the rebuild triggered by setState() does not render the FAB with the new icon.由于this.floatingActionButton仅使用初始图标实例化一次,因此由setState()触发的重建不会使用新图标呈现 FAB。

Try setting your this.floatingActionButton in didChangeDependencies() instead of initState() , since, according to the flutter.dev documentation article on didChangeDependecies , it will be尝试在didChangeDependencies()而不是initState()中设置this.floatingActionButton ,因为根据关于 didChangeDependecies 的 flutter.dev 文档文章,它将是

Called when a dependency of this State object changes.当此 State object 的依赖项发生更改时调用。

Give it a Key .给它一个Key

Everytime the build function is called, it compares those Keys.每次调用构建 function 时,它都会比较这些键。 For example, if you use UniqueKey, your FloatingActionButton always gets rebuild, because it will have a new unique key everytime.例如,如果您使用 UniqueKey,您的 FloatingActionButton 总是会重建,因为它每次都会有一个新的唯一键。 But in this case you should take the build of your FloatingActionButton out of initState() and put it inside of your widget tree.但在这种情况下,您应该从 initState() 中取出 FloatingActionButton 的构建并将其放入小部件树中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM