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

Flutter中如何为不同页面设置不同的系统导航栏颜色?

Flutter中如何为不同页面设置不同的系统导航栏颜色?

我太懂这种踩坑的感觉了——重复写导航栏颜色设置的代码不说,颜色还不听话,一会儿正常一会儿出问题,确实让人头大。咱们先捋清楚你当前代码的问题,再给你几个更靠谱的复用方案。

为什么你的代码会出现颜色异常?

你当前在页面的initState里设置绿色导航栏,dispose里恢复白色,但这里有个关键的点:dispose方法只有当页面被彻底从路由栈中移除(比如用户pop出页面且不会再返回)时才会执行。

举个例子:当你从绿色页面push到另一个页面时,绿色页面其实还在路由栈里,并没有被销毁,所以它的dispose根本没触发;等你从新页面返回绿色页面时,绿色页面的initState也不会再次执行,这就导致导航栏一直停留在新页面设置的白色,只有当绿色页面被彻底销毁再重新创建时,颜色才会正常——这就是为什么只有一个页面能正常显示绿色的原因。

方案一:封装工具类+页面可见性监听

首先把导航栏颜色设置的逻辑抽成工具类,避免重复写代码:

import 'package:flutter/services.dart';
import 'package:flutter/material.dart';

class SystemNavBarHelper {
  // 设置为绿色导航栏
  static void setGreenNavBar() {
    SystemChrome.setSystemUIOverlayStyle(
      const SystemUiOverlayStyle(
        systemNavigationBarColor: Color.fromARGB(255, 52, 114, 70),
        systemNavigationBarIconBrightness: Brightness.dark,
        statusBarColor: Colors.transparent,
        statusBarIconBrightness: Brightness.dark,
      ),
    );
  }

  // 恢复为白色导航栏
  static void setWhiteNavBar() {
    SystemChrome.setSystemUIOverlayStyle(
      const SystemUiOverlayStyle(
        systemNavigationBarColor: Colors.white,
        systemNavigationBarIconBrightness: Brightness.dark,
        statusBarColor: Colors.transparent,
        statusBarIconBrightness: Brightness.dark,
      ),
    );
  }
}

然后在需要绿色导航栏的页面中,通过WidgetsBindingObserver监听页面的可见状态,确保页面回到前台时能重新设置颜色:

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

  @override
  State<GreenNavBarPage> createState() => _GreenNavBarPageState();
}

class _GreenNavBarPageState extends State<GreenNavBarPage> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    // 添加观察者
    WidgetsBinding.instance.addObserver(this);
    // 初始化时设置绿色
    SystemNavBarHelper.setGreenNavBar();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    // 当页面从后台回到前台时,重新设置绿色(避免被其他操作覆盖)
    if (state == AppLifecycleState.resumed) {
      SystemNavBarHelper.setGreenNavBar();
    }
  }

  @override
  void dispose() {
    // 移除观察者
    WidgetsBinding.instance.removeObserver(this);
    // 只有当页面被彻底销毁时,才恢复白色
    SystemNavBarHelper.setWhiteNavBar();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("绿色导航栏页面")),
      body: const Center(child: Text("这是带有绿色导航栏的页面")),
    );
  }
}

其他需要白色导航栏的页面,如果默认就是白色,只需要在必要的地方调用SystemNavBarHelper.setWhiteNavBar()即可。

方案二:自定义路由观察者(更适合多页面场景)

如果你的App有很多页面需要不同的导航栏颜色,用路由观察者会更省心——它能自动监听页面的push和pop动作,统一处理颜色切换:

先自定义一个路由观察者类:

import 'package:flutter/services.dart';
import 'package:flutter/material.dart';

class NavBarRouteObserver extends NavigatorObserver {
  @override
  void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
    super.didPush(route, previousRoute);
    // 根据当前页面的名称设置对应颜色
    _setNavBarColor(route.settings.name);
  }

  @override
  void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
    super.didPop(route, previousRoute);
    // 当返回上一页时,根据上一页的名称设置颜色
    _setNavBarColor(previousRoute?.settings.name);
  }

  void _setNavBarColor(String? routeName) {
    if (routeName == "/green-page") {
      SystemNavBarHelper.setGreenNavBar();
    } else {
      // 默认设置为白色
      SystemNavBarHelper.setWhiteNavBar();
    }
  }
}

然后在MaterialApp中注册这个观察者:

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '导航栏颜色示例',
      // 注册路由观察者
      navigatorObservers: [NavBarRouteObserver()],
      initialRoute: "/",
      routes: {
        "/": (context) => const WhiteNavBarPage(),
        "/green-page": (context) => const GreenNavBarPage(),
      },
    );
  }
}

这种方式不需要在每个页面里写颜色设置的代码,所有的颜色切换逻辑都集中在观察者里,维护起来更方便。

小提醒

  • 如果你用的是Navigator.push而不是命名路由,可以通过route.settings.arguments传递页面的导航栏颜色标识,在观察者中判断。
  • 测试的时候要注意页面跳转的各种场景:push、pop、后台切前台,确保颜色都能正确切换。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 08:09:30