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

如何根据页面主题更改Flutter中图标与导航栏的颜色

PageView页面切换时同步主题与导航栏/图标颜色实现方案

我需要在PageView中实现图标与导航栏颜色随页面主题变化的效果,项目包含5个页面,其中第2个页面(索引1)固定为深色主题,切换到该页面时,ScreenWrapper内所有元素的主题需同步变更。

修改后完整代码

import 'package:at_app1/features/post/presentation/create_post.dart';
import 'package:at_app1/features/post/presentation/home_page.dart';
import 'package:feather_icons/feather_icons.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

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

  @override
  State<ScreenWrapper> createState() => _ScreenWrapperState();
}

class _ScreenWrapperState extends State<ScreenWrapper> {
  int _currentIndex = 0;
  late ThemeData _currentTheme;

  // 初始化主题
  @override
  void initState() {
    super.initState();
    _currentTheme = ThemeData.light();
    _updateSystemUI(_currentTheme.brightness);
  }

  // 更新系统状态栏与导航栏样式
  void _updateSystemUI(Brightness brightness) {
    SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
      statusBarColor: Colors.transparent,
      statusBarIconBrightness: brightness == Brightness.dark ? Brightness.light : Brightness.dark,
      systemNavigationBarColor: brightness == Brightness.dark ? Colors.black : Colors.white,
      systemNavigationBarIconBrightness: brightness == Brightness.dark ? Brightness.light : Brightness.dark,
    ));
  }

  // 切换主题
  void _switchTheme(int pageIndex) {
    setState(() {
      if (pageIndex == 1) {
        _currentTheme = ThemeData.dark();
      } else {
        _currentTheme = ThemeData.light();
      }
      _updateSystemUI(_currentTheme.brightness);
    });
  }

  final _bottomNavigationBarItems = [
    const BottomNavigationBarItem(
      icon: Icon(FeatherIcons.home),
      activeIcon: Icon(FeatherIcons.home, color: Colors.pink),
      label: '',
    ),
    const BottomNavigationBarItem(
      icon: Icon(FeatherIcons.users),
      activeIcon: Icon(FeatherIcons.users, color: Colors.blue),
      label: '',
    ),
    const BottomNavigationBarItem(
      icon: Icon(FeatherIcons.plusCircle),
      activeIcon: Icon(FeatherIcons.plusCircle, color: Colors.orange),
      label: '',
    ),
    const BottomNavigationBarItem(
      icon: Icon(FeatherIcons.heart),
      activeIcon: Icon(FeatherIcons.heart, color: Colors.purple),
      label: '',
    ),
    const BottomNavigationBarItem(
      icon: Icon(FeatherIcons.bookmark),
      activeIcon: Icon(FeatherIcons.bookmark, color: Colors.yellow),
      label: '',
    ),
  ];

  final PageController _pageController = PageController(initialPage: 0);

  @override
  Widget build(BuildContext context) {
    return Theme(
      data: _currentTheme,
      child: Scaffold(
        extendBodyBehindAppBar: true,
        extendBody: true,
        body: Stack(
          alignment: Alignment.topCenter,
          children: [
            PageView(
              controller: _pageController,
              onPageChanged: (newIndex) {
                setState(() => _currentIndex = newIndex);
                _switchTheme(newIndex);
              },
              children: const [
                HomePage(),
                CreatePostPage(),
                // FollowingPostPage(),
                // CameraExampleHome(),
                // NotificationPage(),
                // SavedPage(),
              ],
            ),
            Positioned(
              top: 0,
              left: 0,
              right: 0,
              child: AppBar(
                backgroundColor: Colors.transparent,
                leadingWidth: 50,
                leading: Padding(
                  padding: EdgeInsets.only(left: MediaQuery.of(context).size.width * 0.05),
                  child: GestureDetector(
                    onTap: () {},
                    child: CircleAvatar(backgroundColor: Colors.grey),
                  ),
                ),
                elevation: 0,
                iconTheme: IconThemeData(color: _currentTheme.brightness == Brightness.dark ? Colors.white : Colors.black),
                actions: [
                  Stack(
                    alignment: Alignment.center,
                    children: [
                      Icon(Icons.circle, color: Colors.red.withOpacity(0.7), size: 40),
                      IconButton(
                        onPressed: () {},
                        icon: const Icon(Icons.flag_outlined, size: 20, color: Colors.white),
                      ),
                    ],
                  ),
                  Padding(
                    padding: EdgeInsets.only(right: MediaQuery.of(context).size.width * 0.03),
                    child: Stack(
                      alignment: Alignment.center,
                      children: [
                        Icon(Icons.circle, color: Colors.yellow.withOpacity(0.7), size: 40),
                        IconButton(
                          onPressed: () {},
                          icon: const Icon(Icons.search, size: 20, color: Colors.white),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
        bottomNavigationBar: Container(
          height: MediaQuery.of(context).size.height * 0.08,
          color: _currentTheme.brightness == Brightness.dark ? Colors.black : Colors.white,
          child: BottomNavigationBar(
            unselectedFontSize: 0,
            selectedFontSize: 0,
            iconSize: 30,
            currentIndex: _currentIndex,
            items: _bottomNavigationBarItems,
            type: BottomNavigationBarType.fixed,
            unselectedItemColor: _currentTheme.brightness == Brightness.dark ? Colors.grey[400] : Colors.grey[600],
            backgroundColor: Colors.transparent,
            elevation: 0,
            onTap: (index) {
              _pageController.animateToPage(
                index,
                duration: const Duration(milliseconds: 300),
                curve: Curves.ease,
              );
            },
          ),
        ),
      ),
    );
  }
}

关键修改说明

  1. 新增主题状态变量:通过_currentTheme控制全局主题,初始化时设为浅色主题
  2. 系统UI同步更新:封装_updateSystemUI方法,根据主题亮度自动切换状态栏、导航栏图标颜色与背景色
  3. 主题切换逻辑:在onPageChanged中判断页面索引,切换至对应主题并触发状态更新
  4. 全局主题包裹:用Theme组件包裹Scaffold,让内部所有子组件自动继承当前主题样式
  5. 导航栏适配:调整BottomNavigationBar的未选中图标颜色、背景色,跟随主题变化
  6. AppBar优化:设置iconTheme让AppBar图标颜色随主题切换,保持视觉一致性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 10:47:08