Flutter系统导航栏和状态栏颜色

38

我该如何使用Android Studio和flutter更改系统NavBar?

我猜它不在main.dart中,我需要通过Android系统文件来实现,但是当我尝试编辑style.xml时,主题编辑器不允许我编辑任何颜色。

任何帮助都将不胜感激,我想要一个浅色的NavBar来配合一个浅色的底部AppBar。

3个回答

68

注意:这需要一个更近期的Flutter版本,因为它引用了在2018年6月添加的API。

您可以使用默认构造函数创建自定义SystemUiOverlayStyle。系统导航栏的颜色在那里定义。但是,为了避免设置大量的空值,请使用copyWith方法从现有的浅色/深色主题中更新值。

const mySystemTheme= SystemUiOverlayStyle.light
 .copyWith(systemNavigationBarColor: Colors.red);

您可以使用SystemChrome静态方法来命令式地设置系统导航栏颜色。

SystemChrome.setSystemUiOverlayStyle(mySystemTheme);

但是,如果您有多个小部件设置了这个值,或者使用了材料AppBar或Cupertino NavBar,它们可能会覆盖您的值。相反,您可以使用新的AnnotatedRegion API来告诉Flutter在某些小部件可见时自动切换到这个样式。例如,如果您想在特定路线中任何时候使用上面的主题,您可以像这样将其包装在一个AnnotatedRegion小部件中。

Widget myRoute(BuildContext context) {
  return new AnnotatedRegion<SystemUiOverlayStyle>(
    value: mySystemTheme,
    child: new MyRoute(),
  );
}

如果您弹出路由,则此操作不会将您的主题更改回先前的值。


2
目前Flutter视图将系统Chrome值组合在实际的层树中,这些值在屏幕顶部和底部相交。因此,如果您的屏幕顶部有3个注释区域,则会选择最后一个。这是一种较低级别的API,我们打算在Material和Cupertino上构建一个更简单的API。 - Jonah Williams
“last” 的意思是最深层的,除非它没有尺寸 :) - Jonah Williams
1
@JonahWilliams你说,“如果你弹出路由,这不会将你的主题改回以前的值”。在弹出或推入新路由后,是否有更改状态栏颜色的选项? - pso
2
@JonahWilliams 我尝试将 AnnotatedRegion 作为 Scaffold 的父级,并定义 statusBarColor: Colors.transparent,但它不起作用,似乎 AppBar 总是优先。 - Michel Feinstein
1
那么,pop的解决方案是什么? - BeHappy
显示剩余3条评论

53

Flutter 2.4+(更新)

使用systemOverlayStyle属性

class MyPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        systemOverlayStyle: SystemUiOverlayStyle(
          systemNavigationBarColor: Colors.blue, // Navigation bar
          statusBarColor: Colors.pink, // Status bar
        ),
      ),
    );
  }
}

8
没效果。 - Tom
不确定你是怎么做的。你能把它发成一个问题吗? - CopsOnRoad
我刚刚把你的代码复制到主函数里了。非常感谢! - Tom
1
这应该被接受为答案。注意:仅适用于最近的Android版本。 - rubStackOverflow
1
无法在最新的安卓版本上运行。 - Jeremi
@Jeremi 你可以在 Github 上提交问题 - CopsOnRoad

15

您可以简单地调用SystemChrome.setSystemUIOverlayStyle

import 'package:flutter/services.dart'

SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);

2
这个方法可以用,但有时候会比较难搞,需要热重载几次才能生效,不过现在这样也比没有好! - Tom O'Sullivan
1
它在IOS上不起作用。 - Tom
@Tom,你能在iOS上运行这段代码吗? - Abdullah Riaz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接