如何在颤动的选中和未选中状态下更改选项卡图标的颜色?

时间:2018-12-28 10:20:33

标签: flutter

我想在选项卡中定义图标的未选择颜色,就像unselectedLabelColor一样。

  TabBar(
          indicatorColor: Colors.grey,
          labelColor: Colors.black,
          unselectedLabelColor: Colors.grey,
          tabs: [
            Tab(
                text: 'first',
                icon: Icon(Icons.directions_car, color: Colors.grey)),
            Tab(
                text: 'second',
                icon: Icon(Icons.directions_transit, color: Colors.grey)),
            Tab(
                text: 'third',
                icon: Icon(Icons.directions_bike, color: Colors.grey)),
          ],
        )

9 个答案:

答案 0 :(得分:5)

按照Britannio的指示,我已经解决了我的问题,但是我想分享我的解决方案,以便它可以帮助其他人。我对必须用空主体调用setState()感到困惑,不建议这样做,因此,如果有人有更好的解决方案,请发表评论。我将对其进行更新。

     TabController _tabController;

     @override
     void initState() {
       super.initState();
      _tabController = new TabController(vsync: this, length: 3);
      _tabController.addListener(_handleTabSelection);
     }

     void _handleTabSelection() {
        setState(() {
         });
     }

     TabBar(
            controller: _tabController,
            indicatorColor: Colors.grey,
            labelColor: Colors.black,
            unselectedLabelColor: Colors.grey,
            tabs: [
              Tab(
                  text: 'Sale',
                  icon: Icon(Icons.directions_car,
                      color: _tabController.index == 0
                          ? Colors.black
                          : Colors.grey)),
              Tab(
                  text: 'Latest',
                  icon: Icon(Icons.directions_transit,
                      color: _tabController.index == 1
                          ? Colors.black
                          : Colors.grey)),
              Tab(
                  text: 'Popular',
                  icon: Icon(Icons.directions_bike,
                      color: _tabController.index == 2
                          ? Colors.black
                          : Colors.grey)),
            ],
          )

答案 1 :(得分:5)

使用标签栏中的图像图标时使用的代码。

它也可以与选项卡和滑动一起正常使用。

TabBar(
      tabs: [
        Tab(
            text: 'one',
            icon: CustomIcon('assets/1.png', size: 24,)),
        Tab(
            text: 'two',
            icon: CustomIcon('assets/2.png', size: 24,)),
      ],
    )

----------------------------------------

class CustomIcon extends StatelessWidget{
  const CustomIcon(this.name, { Key key, this.size, this.color, }) : super(key: key);

  final String name;
  final double size;
  final Color color;

  @override
  Widget build(BuildContext context) {

    final IconThemeData iconTheme = IconTheme.of(context);
    final double iconOpacity = iconTheme.opacity;
    Color iconColor = color ?? iconTheme.color;

    if (iconOpacity != 1.0) iconColor = iconColor.withOpacity(iconColor.opacity * iconOpacity);
    return Image.asset(name, color: iconColor, height: size,);
  }
}

答案 2 :(得分:3)

从图标中删除属性“颜色”将使用在 unselectedLabelColor 上设置的默认颜色。

TabBar(
  indicatorColor: Colors.grey,
  labelColor: Colors.black,
  unselectedLabelColor: Colors.grey,
  tabs: [
    Tab(
        text: 'first',
        icon: Icon(Icons.directions_car)),
    Tab(
        text: 'second',
        icon: Icon(Icons.directions_transit)),
    Tab(
        text: 'third',
        icon: Icon(Icons.directions_bike)),
  ],
)

答案 3 :(得分:2)

有两种方法

  1. 您可以使用activeIcon
BottomNavigationBarItem(
        activeIcon: ,
        icon: ,
  1. 您可以使用其他字段:
IconData selectedItem = Icons.dashboard;

List<IconData> itemsList = [
  Icons.dashboard,
  Icons.location_on,
  Icons.notifications,
  Icons.account_circle,
];

//...
  BottomNavigationBar(
      onTap: (int index) {
        setState(() {
          selectedItem = itemsList[index];
        });
      },
      currentIndex: itemsList.indexOf(selectedItem),
      items: itemsList.map((data) {
        return BottomNavigationBarItem(
          icon: selectedItem == data
              ? Icon(data, color: Colors.grey)
              : Icon(data, color: Colors.grey),
          title: Container(),
        );
      }).toList());

UPD: 对于Tab,没有activeIcon,因此,您似乎可以使用第二种方式

答案 4 :(得分:2)

  1. 创建一个自定义标签控制器,如图here
  2. 执行类似_tabController.index的操作来获取当前标签的索引。
  3. 对于每个选项卡,检查其位置(从0开始)是否与TabController索引匹配并显示适当的图标

答案 5 :(得分:2)

现在,您只需更改 labelColor 属性的颜色

bottomNavigationBar: TabBar(
    tabs: [

    ],
    labelColor: Colors.deepPurpleAccent,
  ),

答案 6 :(得分:2)

我的情况是,我使用资产中的自定义图片,此代码对我有用。

TabBar(
  indicatorColor: Colors.grey,
  labelColor: Colors.black,
  unselectedLabelColor: Colors.grey,
  tabs: [
    Tab(
        text: 'first',
        icon: ImageIcon(AssetImage('assets/1.png')
    ),
    Tab(
        text: 'second',
        icon: ImageIcon(AssetImage('assets/2.png')
    ),
    Tab(
        text: 'third',
        icon: ImageIcon(AssetImage('assets/3.png')
    ),
  ],
)

答案 7 :(得分:0)

我使用了不同的方法。我已经使用 flutter_bloc 实现了这一目标。要首先了解这种方法,请参见https://pub.dev/packages/flutter_bloc

注意:如果您使用的是肘节,请不要忘记关闭()它们

首先,我创建了一个肘节类:

import 'package:flutter_bloc/flutter_bloc.dart';

class UICubit<T> extends Cubit<T> {
  T currentState;

  UICubit(T state) : super(state);

  void updateState(T newState) {
    this.currentState = newState;
    emit(currentState);
  }
}

之后,我创建了一个TabIcon类,如下所示:

class TabIcon extends StatelessWidget {
  final Color selectedColor;
  final Color unselectedColor;
  final Icon icon;
  final double size;
  final UICubit<bool> uiCubit;

  TabIcon(this.uiCubit, this.icon, this.selectedColor, this.unselectedColor,
      this.size);

  @override
  Widget build(BuildContext context) {
    return BlocConsumer<UICubit<bool>, bool>(
      cubit: uiCubit,
      listener: (BuildContext context,bool flag) {},
      builder: (BuildContext context, bool flag) {
        return _buildImage(flag?selectedColor:unselectedColor);
      },
    );
  }

  Widget _buildImage(int color) {
    return Image.asset(
      icon,
      width: size,
      height: size,
      color: color,
    );
  }
  
}

现在在父级窗口小部件中,我创建了如下的肘节列表:

List<UICubit<TabState>> cubitList = [];

添加标签页

      List<Tab> tabs = [];
   cubit1 = UICubit<TabState>(true);
   cubitList.add(cubit1);
   tabs.add(Tab(
          text: "First",
          icon: TabIcon(cubit1, Icons.firsIcon, Colors.blue,Colors.grey),
        ),
    
    cubit2 = UICubit<TabState>(false);
    cubitList.add(cubit2);
    tabs.add(Tab(
          text: "Second",
          icon: TabIcon(cubit2, Icons.firsIcon, Colors.blue,Colors.grey),
        ),

现在在选项卡上单击:

TabBar(
      onTap: (index) {
             updateTab(index);
         },
                       
           tabs: tabs,
      ),

updateTab()方法:

  void updateTab(int index) async {
    for (int i = 0; i < cubitList.length; i++) {
      if (i == index) {
        cubitList[i].updateState(true);
      } else {
        cubitList[i].updateState(false);
      }
    }
  }

别忘了在父部件的dispose方法中关闭手肘:

 @override
  void dispose() {
    cubitList.forEach((element) {
      element.close();
    });
    super.dispose();
  }

谢谢,也许有些人不喜欢这种方法,但是这种方法解决了我的问题。

答案 8 :(得分:0)

我认为最好使用TabBarTheme类在单个位置自定义TabBar外观。

ThemeData(
  tabBarTheme: TabBarTheme(
    indicatorSize: TabBarIndicatorSize.tab,
    indicatorColor: Colors.grey,
    labelColor: Colors.black,
    unselectedLabelColor: Colors.grey,
  ),
)