You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter BottomAppBar点击图标颜色不实时更新,仅热重载生效问题

Flutter BottomAppBar点击后颜色不实时更新问题及解决方法

我在Flutter中实现了BottomAppBar,需求是点击底部栏图标时,该图标及文字切换为高亮颜色;点击其他图标时,原选中项恢复默认颜色,当前点击项变为高亮。但目前点击后颜色无变化,仅在热重载后才会更新。

底部栏组件代码

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get_state_manager/src/simple/get_state.dart';
import 'package:unicons/unicons.dart';

import '../../common/constants/colors/colors.dart';
import '../../pages/homepage/controller.dart';

enum BottomBarIcon {
  Home,
  Equalizer,
  Exchange,
  Wallet,
  Ellipsis,
}

class RexBottomBar extends StatelessWidget {
  const RexBottomBar({super.key});

  @override
  Widget build(BuildContext context) {
    return GetBuilder<HomeScreenController>(
      builder: (controller) {
        return BottomAppBar(
          color: Color(0xFF121212),
          child: SizedBox(
            height: 80.h, // Increased height to accommodate the text
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                buildBottomBarItem(
                  icon: Icons.home_outlined,
                  text: 'Home',
                  isSelected: controller.selectedIconIndex.value == 0,
                  onTap: () => controller.setSelectedIcon(0),
                ),
                buildBottomBarItem(
                  icon: Icons.equalizer_sharp,
                  text: 'Markets',
                  isSelected: controller.selectedIconIndex.value == 1,
                  onTap: () => controller.setSelectedIcon(1),
                ),
                buildBottomBarItem(
                  icon: UniconsLine.exchange_alt,
                  text: 'Trade',
                  isSelected: controller.selectedIconIndex.value == 2,
                  onTap: () => controller.setSelectedIcon(2),
                ),
                buildBottomBarItem(
                  icon: UniconsLine.wallet,
                  text: 'Assets',
                  isSelected: controller.selectedIconIndex.value == 3,
                  onTap: () => controller.setSelectedIcon(3),
                ),
                buildBottomBarItem(
                  icon: FontAwesomeIcons.ellipsis,
                  text: 'More',
                  isSelected: controller.selectedIconIndex.value == 4,
                  onTap: () => controller.setSelectedIcon(4),
                ),
              ],
            ),
          ),
        );
      },
    );
  }

  Widget buildBottomBarItem({
    required IconData icon,
    required String text,
    required bool isSelected,
    required VoidCallback onTap,
  }) {
    return GestureDetector(
      onTap: onTap,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(
            icon,
            color:
                isSelected ? AppColor.highlightColor : AppColor.offTextColor2,
            size: 25.sp,
          ),
          SizedBox(height: 5.h),
          Text(
            text,
            style: TextStyle(
              color:
                  isSelected ? AppColor.highlightColor : AppColor.offTextColor2,
              fontSize: 11.sp,
              letterSpacing: -0.6
            ),
          ),
        ],
      ),
    );
  }
}

对应的控制器代码

import 'package:get/get.dart';
import 'package:get/get_state_manager/src/simple/get_controllers.dart';

class HomeScreenController extends GetxController{
  // Bottom Bar
  RxInt selectedIconIndex = 0.obs;

  void setSelectedIcon(int index) {
    selectedIconIndex.value = index;
  }
}

解决方案

  • 为buildBottomBarItem方法添加index参数,用于标识底部栏图标的位置
  • 通过Get.find()获取HomeScreenController实例
  • 使用Obx组件包裹buildBottomBarItem的内容,Obx会监听控制器中selectedIconIndex可观察变量的变化,当变量更新时自动重建内部内容,确保图标颜色实时更新
  • 在Obx内部,根据当前index与控制器中selectedIconIndex是否匹配来判断isSelected状态

修改后的buildBottomBarItem方法示例:

Widget buildBottomBarItem({
  required IconData icon,
  required String text,
  required int index,
  required VoidCallback onTap,
}) {
  final controller = Get.find<HomeScreenController>();
  return GestureDetector(
    onTap: onTap,
    child: Obx(() {
      final isSelected = controller.selectedIconIndex.value == index;
      return Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(
            icon,
            color: isSelected ? AppColor.highlightColor : AppColor.offTextColor2,
            size: 25.sp,
          ),
          SizedBox(height: 5.h),
          Text(
            text,
            style: TextStyle(
              color: isSelected ? AppColor.highlightColor : AppColor.offTextColor2,
              fontSize: 11.sp,
              letterSpacing: -0.6
            ),
          ),
        ],
      );
    }),
  );
}

调用该方法时需传入index参数,示例:

buildBottomBarItem(
  icon: Icons.home_outlined,
  text: 'Home',
  index: 0,
  onTap: () => controller.setSelectedIcon(0),
),

内容的提问来源于stack exchange,提问作者Jesse Josiah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 04:17:07