Flutter:我应该在哪里调用SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark)

时间:2018-12-17 16:19:25

标签: dart flutter

在我的Flutter应用中,屏幕A没有AppBar。 所以我在构建中称呼SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark)

按下另一个具有AppBar的屏幕B,然后将其弹出后, 屏幕A的指示灯状态栏为亮。

我希望在弹出屏幕时系统UI返回到原始设置。

Gif

5 个答案:

答案 0 :(得分:0)

其背后的原因是您的新屏幕将具有自己的生命周期,因此状态栏可能会使用其他颜色。

您可以在SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark)方法中调用initState,但是在弹出堆叠屏幕后不会触发。这里有两个问题,但是您可以从屏幕pop()返回后再次调用。很简单吧?差不多好了。

当您按下AppBar小部件上的后退按钮时,即使仍从堆叠屏幕渲染导航动画,也会从Navigator.of(context).push(someroute)立即返回。 要解决此问题,您可以添加一些“调整”,将在500毫秒后再次设置状态栏颜色,这足以使动画完全完成。因此,您或多或少需要这样的东西:

class HomeScreen extends StatefulWidget {
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  @override
  void initState() {
    _updateAppbar();
    super.initState();
  }

  void _updateAppbar() {
    SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        child: RaisedButton(
            child: Text('Navigate to second screen'),
            onPressed: () => Navigator.of(context)
                .push(MaterialPageRoute(builder: (BuildContext context) => SecondScreen()))
                .whenComplete(() => Future.delayed(Duration(milliseconds: 500)).then((_) => _updateAppbar()))));
  }
}

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
    );
  }
}

尽管这可行,但我仍然好奇是否有人知道一种更好的方法来处理此问题,并保持状态栏颜色绑定到每个屏幕。

答案 1 :(得分:0)

也许可行

SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.transparent)

答案 2 :(得分:0)

将此包添加到您的项目 Need Resume 并将您的屏幕状态扩展ResumableState

import 'package:need_resume/need_resume.dart';

class WelcomeScreen extends StatefulWidget {
  final String title;

  const WelcomeScreen({Key key, this.title}) : super(key: key);
  @override
  _WelcomeScreenState createState() => _WelcomeScreenState();
}

class _WelcomeScreenState extends ResumableState<WelcomeScreen> {
  @override
  void onResume() {
    SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);
    super.onResume();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [],
      ),
    );
  }
}

此解决方案按预期工作,代码更改很少。

答案 3 :(得分:0)

也许你可以像这样用 AnnotatedRegion 包装整个页面小部件:

AnnotatedRegion(
value: _currentStyle,
child: Center(
  child: ElevatedButton(
    child: const Text('Change Color'),
    onPressed: _changeColor,
   ),
 ),
);

您可以在此处查看完整示例: https://api.flutter.dev/flutter/services/SystemChrome/setSystemUIOverlayStyle.html

答案 4 :(得分:-2)

如果希望在首次渲染屏幕A之前应用my-contract-account,则可以在调用SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark)之前先在main函数中调用runApp

此外,如果您有只能执行一次的方法调用,则应该将它们放在build方法中,因为它可能会被多次调用。