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

Flutter中如何为Bottom Navigation Bar的每个项添加背景色?

实现带独立背景色的底部导航栏

下面分别给出Flutter和Android原生的实现方案,还原你需要的每个导航项带独立背景色的效果:


Flutter 实现方案

通过自定义底部导航栏布局,为每个导航项配置独立背景色,代码如下:

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: const BottomNavWithColoredItems(),
    );
  }
}

class BottomNavWithColoredItems extends StatefulWidget {
  const BottomNavWithColoredItems({super.key});

  @override
  State<BottomNavWithColoredItems> createState() => _BottomNavWithColoredItemsState();
}

class _BottomNavWithColoredItemsState extends State<BottomNavWithColoredItems> {
  int _selectedIndex = 0;

  // 导航项配置:图标、标题、背景色、文字颜色
  final List<Map<String, dynamic>> _navItems = [
    {
      'icon': Icons.home,
      'title': '首页',
      'bgColor': const Color(0xFF6366F1),
      'selectedColor': Colors.white,
      'unselectedColor': Colors.grey.shade700,
    },
    {
      'icon': Icons.search,
      'title': '搜索',
      'bgColor': const Color(0xFFEC4899),
      'selectedColor': Colors.white,
      'unselectedColor': Colors.grey.shade700,
    },
    {
      'icon': Icons.add_circle,
      'title': '发布',
      'bgColor': const Color(0xFF10B981),
      'selectedColor': Colors.white,
      'unselectedColor': Colors.grey.shade700,
    },
    {
      'icon': Icons.notifications,
      'title': '通知',
      'bgColor': const Color(0xFFF59E0B),
      'selectedColor': Colors.white,
      'unselectedColor': Colors.grey.shade700,
    },
    {
      'icon': Icons.person,
      'title': '我的',
      'bgColor': const Color(0xFF8B5CF6),
      'selectedColor': Colors.white,
      'unselectedColor': Colors.grey.shade700,
    },
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('带独立背景色的底部导航')),
      body: Center(child: Text('当前选中第${_selectedIndex+1}项')),
      bottomNavigationBar: Container(
        height: 60,
        padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: List.generate(_navItems.length, (index) {
            final item = _navItems[index];
            final isSelected = _selectedIndex == index;
            return GestureDetector(
              onTap: () => _onItemTapped(index),
              child: Container(
                width: 60,
                decoration: BoxDecoration(
                  color: isSelected ? item['bgColor'] : Colors.transparent,
                  borderRadius: BorderRadius.circular(12),
                ),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Icon(
                      item['icon'],
                      color: isSelected ? item['selectedColor'] : item['unselectedColor'],
                      size: 24,
                    ),
                    if (isSelected)
                      Text(
                        item['title'],
                        style: TextStyle(
                          color: item['selectedColor'],
                          fontSize: 10,
                        ),
                      ),
                  ],
                ),
              ),
            );
          }),
        ),
      ),
    );
  }
}

实现说明

  • 用_navItems统一管理所有导航项的配置,方便修改颜色、图标和标题
  • 选中导航项时显示对应背景色,同时显示标题;未选中时透明背景,仅显示图标
  • 通过GestureDetector处理点击事件,更新选中状态

Android 原生实现方案

通过自定义导航项布局+动态设置样式来实现效果:

1. 自定义导航项布局(res/layout/bottom_nav_item.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="8dp">

    <ImageView
        android:id="@+id/icon"
        android:layout_width="24dp"
        android:layout_height="24dp" />

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fontFamily="sans-serif-medium"
        android:textSize="10sp"
        android:visibility="gone" />
</LinearLayout>

2. Activity 代码实现

import android.graphics.Color
import android.os.Bundle
import android.view.MenuItem
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import com.google.android.material.bottomnavigation.BottomNavigationView

class MainActivity : AppCompatActivity() {
    private lateinit var bottomNav: BottomNavigationView
    // 导航项背景色数组
    private val navItemColors = listOf(
        Color.parseColor("#6366F1"),
        Color.parseColor("#EC4899"),
        Color.parseColor("#10B981"),
        Color.parseColor("#F59E0B"),
        Color.parseColor("#8B5CF6")
    )
    // 图标资源ID
    private val iconIds = listOf(
        R.drawable.ic_home,
        R.drawable.ic_search,
        R.drawable.ic_add,
        R.drawable.ic_notification,
        R.drawable.ic_profile
    )
    // 导航标题文字
    private val titleTexts = listOf("首页", "搜索", "发布", "通知", "我的")

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        bottomNav = findViewById(R.id.bottom_nav)
        setupBottomNav()
    }

    private fun setupBottomNav() {
        bottomNav.menu.clear()
        // 动态添加导航项
        for (i in navItemColors.indices) {
            val menuItem = bottomNav.menu.add(0, i, i, titleTexts[i])
            menuItem.icon = ContextCompat.getDrawable(this, iconIds[i])
        }

        // 设置选中监听
        bottomNav.setOnItemSelectedListener { menuItem ->
            updateNavItems(menuItem.itemId)
            true
        }

        // 默认选中第一项
        updateNavItems(0)
    }

    private fun updateNavItems(selectedIndex: Int) {
        // 遍历所有导航项,更新样式
        for (i in 0 until bottomNav.menu.size()) {
            val menuItem = bottomNav.menu.getItem(i)
            val itemView = bottomNav.findViewById<View>(menuItem.itemId)
            val icon = itemView.findViewById<ImageView>(R.id.icon)
            val title = itemView.findViewById<TextView>(R.id.title)

            if (i == selectedIndex) {
                // 选中状态:设置背景色、白色图标和文字
                itemView.setBackgroundColor(navItemColors[i])
                icon.setColorFilter(Color.WHITE)
                title.text = titleTexts[i]
                title.visibility = View.VISIBLE
                title.setTextColor(Color.WHITE)
            } else {
                // 未选中状态:透明背景、灰色图标、隐藏文字
                itemView.setBackgroundColor(Color.TRANSPARENT)
                icon.setColorFilter(Color.GRAY)
                title.visibility = View.GONE
            }
        }
    }
}

实现说明

  • 自定义导航项布局,灵活控制图标和标题的显示
  • 动态添加导航项,通过数组统一管理每个项的颜色、图标和文字
  • 选中时切换背景色并显示标题,未选中时恢复默认样式

内容的提问来源于stack exchange,提问作者Ashirwad Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 05:51:18