更改每个屏幕的状态栏颜色

Change statusbar color for each screen

我想为每个屏幕设置状态栏颜色。 例如。在屏幕 A 中,状态栏颜色为红色,在屏幕 B 中,状态栏颜色为蓝色。 我尝试了很多解决方案。但每个人都有自己的问题。 喜欢:

AnnotatedRegion(
    value: SystemUiOverlayStyle(
        systemNavigationBarColor: navigationBarColor,
        statusBarColor: statusBarColor,
    ),
    child: child,
);

或在构建方法中 return 之前:

SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
  statusBarColor: Colors.white
));

我最后的尝试:

  static void pushNamed({
    BuildContext context,
    String route,
    Object arguments,
    Color statusBarColor,
    Color navigationBarColor = Colors.black,
  }) async {
    if (statusBarColor != null) {
      await FlutterStatusbarcolor.setStatusBarColor(statusBarColor);
    }
    await Navigator.pushNamed(
      context,
      route,
      arguments: arguments,
    );
  }

但有时会失败。 这个解决方案的另一个问题是当使用后退按钮时,颜色没有改变。(我在 appbar 中为后退按钮编写代码)。 甚至在热重载时颜色更改为以前的颜色。 我该如何处理这个问题?

更新 #2

我为我的路由创建了一个 class。

static void pushNamedAndRemoveUntil({
    BuildContext context,
    String route,
    Object arguments,
    Color statusBarColor,
    Color popStatucBarColor,
    Color popNavigationBarColor,
    Color navigationBarColor,
}) async {
    changeSystemColor(statusBarColor, navigationBarColor);
    Navigator.pushNamedAndRemoveUntil(
        context,
        route,
        (Route<dynamic> route) => false,
        arguments: arguments,
    ).then((res) {
        changeSystemColor(popStatucBarColor, popNavigationBarColor);
    });
}

和:

void changeSystemColor(Color statusBarColor, Color navigationBarColor) {
  if (statusBarColor != null)
    SystemChrome.setSystemUIOverlayStyle(
      SystemUiOverlayStyle(
        systemNavigationBarColor: navigationBarColor ?? Colors.black,
        statusBarColor: statusBarColor,
      ),
    );
}

并使用此

Routing.pushNamedAndRemoveUntil(
    context: context,
    route: Routes.homeScreen,
    arguments: user,
    statusBarColor: Colors.teal,
);

现在在使用 pushNamedAndRemoveUntil 时不起作用。

您可以使用 AppBar,但将其高度和高度设置为 0,以便它仅覆盖状态栏而没有阴影。

appBar: PreferredSize(
                preferredSize: Size.fromHeight(0),
                child: new AppBar(
                        brightness: Brightness.light,
                        backgroundColor: backgroundColour,
                        elevation: 0,
                )
),

然后在initState()中可以将状态栏设为透明,这样就不会掉色了。

您需要在 await Navigator.push() 调用之前和之后调用它。

SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
   statusBarColor: desiredColour
));

您不能在 initState 或任何其他有状态小部件生命周期方法上触发系统颜色更改。最好的方法似乎是在导航到新视图之前以及从该视图 return 时设置颜色:

void goToWhiteView(){
  changeSystemColor(Colors.white);
  Navigator.pushNamed(
    context,
    route,
    arguments: arguments,
  ).then((result){
    changeSystemColor(Colors.blue);
  });
}

void changeSystemColor(Color color){
  SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
    systemNavigationBarColor: color,
    statusBarColor: color
  ));
}

我创建了 ScreenContainer 小部件并用它包裹我的屏幕:

    return AnnotatedRegion<SystemUiOverlayStyle>(
      value: SystemUiOverlayStyle(
        statusBarColor: statusbarcolor ?? ColorPalette.accent,
        statusBarIconBrightness: statusBarIconBrightness ?? Brightness.light,
      ),
      child: child,
    );

对要设置statusBarColor的页面使用focus_detector

@override
Widget build(BuildContext context) =>
    FocusDetector(
      onVisibilityGained: () {
        //Here you can change statusBarColor as you like
        SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle.dark
        .copyWith(statusBarColor: Colors.transparent);
    SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
      },
      child: YourOwnPage(),
    );

更多信息见visibility_detector