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

Posted

技术标签:

【中文标题】Flutter:按下时如何更改BottomNavBar中的FloatingactionButton图标?【英文标题】:Flutter: How to change the FloatingactionButton icon in the BottomNavBar when pressed? 【发布时间】:2020-02-23 15:51:42 【问题描述】:

单击时,我正在尝试更改底部导航栏中的 FloatingActionButton() 图标。它工作正常,但只有当我离开屏幕并回来时?有谁知道出了什么问题?调用 changeIcon() 中的 Setstate 应该强制重新渲染,还是我错了?

我真的很感激一些帮助:)

编辑: 如果我将 if this.pressed bool 语句作为孩子输入,它甚至都不起作用。 this.pressed 标志的状态从 false 更改为 true(打印状态),但即使这样也不会导致按钮更改其图标。

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

这里附上代码:

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'))
      ],
    );
  

【问题讨论】:

【参考方案1】:

您正在更改状态中的图标并为其使用setState(),这很好,但请注意setState() 正在使用Scaffold 重建您的小部件树,其floatingActionButton 参数为floatingActionButton: this.floatingActionButton,并且您在 initState() 方法中设置您的 this.floatingActionButton,该方法只会被调用一次(每当实例化整个 Widget 时)。由于 this.floatingActionButton 仅使用初始图标实例化一次,因此 setState() 触发的重建不会使用新图标呈现 FAB。

尝试将this.floatingActionButton 设置为didChangeDependencies() 而不是initState(),因为根据flutter.dev documentation article on didChangeDependecies,它将是

在此 State 对象的依赖项发生更改时调用。

【讨论】:

感谢您的快速帮助。我删除了 initiState() 方法并在 didChangeDependencies() 中设置了 this.floatingActonButton。但是,它仍然会更改图标,仅在我切换屏幕并返回后才会更改:( 您是否尝试过创建一个新的 FAB 而不是重用旧的?比如floatingActionButton:getFloatingActionButton()

以上是关于Flutter:按下时如何更改BottomNavBar中的FloatingactionButton图标?的主要内容,如果未能解决你的问题,请参考以下文章

按下时如何更改 IconButton 的图标

在按下时查看:按下时更改背景颜色?如何显示正在按下视图?

鼠标左键按下时如何更改鼠标光标?

如何在焦点/按下时更改 ImageButton 的色调

使用 TouchableHighlight 在 React Native 中按下时如何更改按钮颜色?

SwiftUI,按下时如何更改视图(不使用按钮)颜色?