如何更改 Flutter 中的状态栏和应用栏颜色?
How to change Status Bar and App Bar color in Flutter?
我正在尝试将系统状态栏的颜色更改为黑色。
该配置似乎被 AppBar class 覆盖了。我可以通过在创建 Material 应用程序时将主题分配给 ThemeData.dark()
,然后指定 appBar attribute
来实现我想要的效果。但是我不想要AppBar,而且,这样做会改变所有字体颜色。
一个可能的解决方案是将ThemeData.bright()继承到一个新的class中,然后添加一些仅通过
改变系统状态栏的东西
setSystemUIOverlayStyle
然后我需要指定 AppBar 并以某种方式使其不可见?
main.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:english_words/english_words.dart';
import 'layout_widgets.dart' as layout_widgets;
class RandomWords extends StatefulWidget {
@override
createState() => new RandomWordsState();
}
class RandomWordsState extends State<RandomWords> {
final _suggestions = <WordPair>[];
final _saved = new Set<WordPair>();
final _biggerFont = const TextStyle(fontSize: 18.0);
void _pushSaved() {
Navigator.of(context).push(
new MaterialPageRoute(
builder: (context) {
final tiles = _saved.map((pair) {
return new ListTile(
title: new Text(pair.asPascalCase,style:_biggerFont)
);
}
);
final divided = ListTile.divideTiles(
context:context,
tiles: tiles,).toList();
return new Scaffold(
appBar: new AppBar(
title: new Text('Saved Suggestions'),
),
body: new ListView(children:divided),
);
}
)
);
}
Widget _buildSuggestions() {
return new ListView.builder(
padding: const EdgeInsets.all(16.0),
// The item builder callback is called once per suggested word pairing,
// and places each suggestion into a ListTile row.
// For even rows, the function adds a ListTile row for the word pairing.
// For odd rows, the function adds a Divider widget to visually
// separate the entries. Note that the divider may be difficult
// to see on smaller devices.
itemBuilder: (context, i) {
// Add a one-pixel-high divider widget before each row in theListView.
if (i.isOdd) return new Divider();
// The syntax "i ~/ 2" divides i by 2 and returns an integer result.
// For example: 1, 2, 3, 4, 5 becomes 0, 1, 1, 2, 2.
// This calculates the actual number of word pairings in the ListView,
// minus the divider widgets.
final index = i ~/ 2;
// If you've reached the end of the available word pairings...
if (index >= _suggestions.length) {
// ...then generate 10 more and add them to the suggestions list.
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
}
);
}
Widget _buildRow(WordPair pair) {
final alreadySaved = _saved.contains(pair);
return new ListTile(
title: new Text(
pair.asPascalCase,
style: _biggerFont,
),
trailing: new Icon(
alreadySaved ? Icons.favorite : Icons.favorite_border,
color: alreadySaved ? Colors.red : null,
),
onTap: () {
setState(() {
if (alreadySaved) {
_saved.remove(pair);
} else {
_saved.add(pair);
}
});
},
);
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Startup Name Generator'),
actions: <Widget>[
new IconButton(icon:new Icon(Icons.list), onPressed: _pushSaved),
],
),
body: _buildSuggestions(),
);
}
}
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
Column buildButtonColumn(IconData icon, String label) {
Color color = Theme.of(context).primaryColor;
return new Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Icon(icon, color: color),
new Container(
margin: const EdgeInsets.only(top:8.0),
child: new Text(
label,
style: new TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.w400,
color: color,
)
),
)
],
);
}
Widget titleSection = layout_widgets.titleSection;
Widget buttonSection = new Container(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
buildButtonColumn(Icons.contact_mail, "CONTACT"),
buildButtonColumn(Icons.folder_special, "PORTFOLIO"),
buildButtonColumn(Icons.picture_as_pdf, "BROCHURE"),
buildButtonColumn(Icons.share, "SHARE"),
],
)
);
Widget textSection = new Container(
padding: const EdgeInsets.all(32.0),
child: new Text(
'''
The most awesome apps done here.
''',
softWrap: true,
),
);
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);
return new MaterialApp(
title: 'Startup Name Generator',
// theme: new ThemeData(
// brightness: Brightness.dark,
// primarySwatch: Colors.blue,
// ),
// theme: new ThemeData(),
debugShowCheckedModeBanner: false,
home: new Scaffold(
// appBar: new AppBar(
//// title: new Text('Top Lakes'),
//// brightness: Brightness.light,
// ),
// backgroundColor: Colors.white,
body: new ListView(
children: [
new Padding(
padding: new EdgeInsets.fromLTRB(0.0, 40.0, 0.0, 0.0),
child: new Image.asset(
'images/lacoder-logo.png',
width: 600.0,
height: 240.0,
fit: BoxFit.fitHeight,
),
),
titleSection,
buttonSection,
textSection,
],
),
),
);
}
}
layout_widgets.dart
import 'package:flutter/material.dart';
Widget titleSection = new Container(
padding: const EdgeInsets.all(32.0),
child: new Row(children: [
new Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
new Container(
padding: const EdgeInsets.only(bottom: 8.0),
child: new Text(
"Some-Website.com",
style: new TextStyle(
fontWeight: FontWeight.bold,
),
)
),
new Text(
'Small details',
style: new TextStyle(
color: Colors.grey[500],
)
)
],
)),
new Icon(Icons.star,color: Colors.orange[700]),
new Text('100'),
]));
如果你根本不需要AppBar,那么你可以在主函数中调用setSystemUIOverlayStyle
:
void main() async {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
runApp(new MaterialApp(
home: new Scaffold(),
));
}
如果您在一个脚手架中有应用栏,而在另一个脚手架中有 none,那就更棘手了。在那种情况下,我不得不在使用没有应用栏的脚手架推送新路线后调用 setSystemUIOverlayStyle
:
@override
Widget build(BuildContext context) {
final page = ModalRoute.of(context);
page.didPush().then((x) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
});
return new Scaffold();
}
我是 Whosebug 的新手,而且我从未使用过 Flutter,但我发现 this 包似乎让事情变得相对容易。
方法一:使用包
导入后,您需要做的就是添加以下代码片段:
try {
await FlutterStatusbarcolor.setStatusBarColor(Colors.black);
} on PlatformException catch (e) {
print(e);
}
替换 setStatusBarColor()
的参数应该会给您想要的结果,可以找到完整的颜色列表 here。
方法二:使用默认函数
如果这不起作用/您不想添加额外的包或库,那么 Whosebug 答案可能会有所帮助。
它涉及使用与上述方法类似的功能:getWindow().setStatusBarColor()
或getActivity().getWindow().setStatusBarColor()
用所需的十六进制代码替换参数 from the same list as earlier 也可能得到解决方案。
希望如此works/helps!
更新:
Scaffold(
appBar: AppBar(
systemOverlayStyle: SystemUiOverlayStyle(
systemNavigationBarColor: Colors.blue, // Navigation bar
statusBarColor: Colors.pink, // Status bar
),
),
)
旧的解决方案(仍然有效)
iOS和Android:
appBar: AppBar(
backgroundColor: Colors.red, // status bar and navigation bar color
brightness: Brightness.light, // status bar brightness
)
仅适用于 Android(更灵活)
您可以使用 SystemChrome
class 来更改状态栏和导航栏的颜色。
首先导入
import 'package:flutter/services.dart';
在此之后,您需要添加以下行(最好将这些行放在您的 main()
方法中)
void main() {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
systemNavigationBarColor: Colors.blue,
statusBarColor: Colors.pink,
));
}
我尝试了方法 SystemChrome.setSystemUIOverlayStyle()
,据我测试(Flutter SDK v1.9.1+hotfix.2,运行 on iOS 12.1)它非常适合 Android。但是对于 iOS,例如如果您的第一个屏幕 FirstScreen()
没有 AppBar
,但第二个屏幕 SecondScreen()
有,那么在启动时该方法会在 FirstScreen()
中设置颜色。但是,从 SecondScreen()
导航回 FirstScreen()
后,状态栏颜色变为透明。
我通过设置一个零高度的 AppBar()
想出了一个 hacky 解决方法,然后 AppBar 改变了状态栏的颜色,但 AppBar 本身是不可见的。希望对某人有用。
// FirstScreen that doesn't need an AppBar
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(0),
child: AppBar( // Here we create one to set status bar color
backgroundColor: Colors.black, // Set any color of status bar you want; or it defaults to your theme's primary color
)
)
);
}
// SecondScreen that does have an AppBar
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar()
}
}
这是 FirstScreen
在 iPhone Xs Max iOS 12.1 中的截图:
我做到了
@override
void initState() {
super.initState();
// Transparent status bar
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(statusBarColor: Colors.transparent,));
}
你也可以在逗号后看到不同的属性
SystemUiOverlayStyle(statusBarColor: Colors.transparent,)
只需在逗号后使用 ctrl + space 的组合,您就会得到您可以使用的内容。
请阅读这篇文章flutter package。要将状态栏文本设置为黑色,可以设置FlutterStatusbarcolor.setStatusBarWhiteForeground(false)
。你需要在 didChangeAppLifecycleState
方法中使用 resume state 这行代码,这样当你转到其他应用程序并返回时,状态栏文本颜色设置为你的初始颜色设置。
此外,您需要设置 AppBar 的 TextTheme。喜欢以下。
Widget build(BuildContext context) {
FlutterStatusbarcolor.setStatusBarWhiteForeground(false);
return MaterialApp(
title:// title goes here
theme:// your theme goes here
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
title: _loadAppBarTitle(),
textTheme: Theme.of(context).textTheme),
body: //body's goes here
);
);
希望这篇文章能帮到和我有类似问题的人。
TLDR; 您需要使用 Scaffold
,即使您来回导航,它也会管理颜色。
Scaffold(
appBar: AppBar(brightness: Brightness.dark), \ dark content -> white app bar
body: ...
);
如果您的屏幕没有应用栏,那么您需要使用AnnotatedRegion
和脚手架才能达到同样的效果。
AnnotatedRegion(
value: SystemUiOverlayStyle.light, // this will make the app bar white
child: Scaffold(
body:
),
);
而不是SystemUiOverlayStyle.light
,您可以自定义它:
SystemUiOverlayStyle(
statusBarBrightness: Brightness.light,
systemNavigationBarDividerColor: Colors.blue,
...
);
颤振 2.5.1
'brightness' is deprecated and shouldn't be used. This property is no longer used, please use systemOverlayStyle instead. This feature was deprecated after v2.4.0-0.0.pre.. Try replacing the use of the deprecated member with the replacement.
旧代码
brightness: Brightness.dark,
新密码
systemOverlayStyle: SystemUiOverlayStyle(
systemNavigationBarColor: Colors.blue, // Navigation bar
statusBarColor: Colors.red, // Status bar
),
把这段代码写在AppBar里面就可以了
Scaffold(
drawer: const SideBar(),
appBar: AppBar(
title: const Text("SomeThing"),
systemOverlayStyle: SystemUiOverlayStyle.dark,//this is what you wanted
),
body: YourWidget()
我正在尝试将系统状态栏的颜色更改为黑色。
该配置似乎被 AppBar class 覆盖了。我可以通过在创建 Material 应用程序时将主题分配给 ThemeData.dark()
,然后指定 appBar attribute
来实现我想要的效果。但是我不想要AppBar,而且,这样做会改变所有字体颜色。
一个可能的解决方案是将ThemeData.bright()继承到一个新的class中,然后添加一些仅通过
改变系统状态栏的东西setSystemUIOverlayStyle
然后我需要指定 AppBar 并以某种方式使其不可见?
main.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:english_words/english_words.dart';
import 'layout_widgets.dart' as layout_widgets;
class RandomWords extends StatefulWidget {
@override
createState() => new RandomWordsState();
}
class RandomWordsState extends State<RandomWords> {
final _suggestions = <WordPair>[];
final _saved = new Set<WordPair>();
final _biggerFont = const TextStyle(fontSize: 18.0);
void _pushSaved() {
Navigator.of(context).push(
new MaterialPageRoute(
builder: (context) {
final tiles = _saved.map((pair) {
return new ListTile(
title: new Text(pair.asPascalCase,style:_biggerFont)
);
}
);
final divided = ListTile.divideTiles(
context:context,
tiles: tiles,).toList();
return new Scaffold(
appBar: new AppBar(
title: new Text('Saved Suggestions'),
),
body: new ListView(children:divided),
);
}
)
);
}
Widget _buildSuggestions() {
return new ListView.builder(
padding: const EdgeInsets.all(16.0),
// The item builder callback is called once per suggested word pairing,
// and places each suggestion into a ListTile row.
// For even rows, the function adds a ListTile row for the word pairing.
// For odd rows, the function adds a Divider widget to visually
// separate the entries. Note that the divider may be difficult
// to see on smaller devices.
itemBuilder: (context, i) {
// Add a one-pixel-high divider widget before each row in theListView.
if (i.isOdd) return new Divider();
// The syntax "i ~/ 2" divides i by 2 and returns an integer result.
// For example: 1, 2, 3, 4, 5 becomes 0, 1, 1, 2, 2.
// This calculates the actual number of word pairings in the ListView,
// minus the divider widgets.
final index = i ~/ 2;
// If you've reached the end of the available word pairings...
if (index >= _suggestions.length) {
// ...then generate 10 more and add them to the suggestions list.
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
}
);
}
Widget _buildRow(WordPair pair) {
final alreadySaved = _saved.contains(pair);
return new ListTile(
title: new Text(
pair.asPascalCase,
style: _biggerFont,
),
trailing: new Icon(
alreadySaved ? Icons.favorite : Icons.favorite_border,
color: alreadySaved ? Colors.red : null,
),
onTap: () {
setState(() {
if (alreadySaved) {
_saved.remove(pair);
} else {
_saved.add(pair);
}
});
},
);
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Startup Name Generator'),
actions: <Widget>[
new IconButton(icon:new Icon(Icons.list), onPressed: _pushSaved),
],
),
body: _buildSuggestions(),
);
}
}
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
Column buildButtonColumn(IconData icon, String label) {
Color color = Theme.of(context).primaryColor;
return new Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Icon(icon, color: color),
new Container(
margin: const EdgeInsets.only(top:8.0),
child: new Text(
label,
style: new TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.w400,
color: color,
)
),
)
],
);
}
Widget titleSection = layout_widgets.titleSection;
Widget buttonSection = new Container(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
buildButtonColumn(Icons.contact_mail, "CONTACT"),
buildButtonColumn(Icons.folder_special, "PORTFOLIO"),
buildButtonColumn(Icons.picture_as_pdf, "BROCHURE"),
buildButtonColumn(Icons.share, "SHARE"),
],
)
);
Widget textSection = new Container(
padding: const EdgeInsets.all(32.0),
child: new Text(
'''
The most awesome apps done here.
''',
softWrap: true,
),
);
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);
return new MaterialApp(
title: 'Startup Name Generator',
// theme: new ThemeData(
// brightness: Brightness.dark,
// primarySwatch: Colors.blue,
// ),
// theme: new ThemeData(),
debugShowCheckedModeBanner: false,
home: new Scaffold(
// appBar: new AppBar(
//// title: new Text('Top Lakes'),
//// brightness: Brightness.light,
// ),
// backgroundColor: Colors.white,
body: new ListView(
children: [
new Padding(
padding: new EdgeInsets.fromLTRB(0.0, 40.0, 0.0, 0.0),
child: new Image.asset(
'images/lacoder-logo.png',
width: 600.0,
height: 240.0,
fit: BoxFit.fitHeight,
),
),
titleSection,
buttonSection,
textSection,
],
),
),
);
}
}
layout_widgets.dart
import 'package:flutter/material.dart';
Widget titleSection = new Container(
padding: const EdgeInsets.all(32.0),
child: new Row(children: [
new Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
new Container(
padding: const EdgeInsets.only(bottom: 8.0),
child: new Text(
"Some-Website.com",
style: new TextStyle(
fontWeight: FontWeight.bold,
),
)
),
new Text(
'Small details',
style: new TextStyle(
color: Colors.grey[500],
)
)
],
)),
new Icon(Icons.star,color: Colors.orange[700]),
new Text('100'),
]));
如果你根本不需要AppBar,那么你可以在主函数中调用setSystemUIOverlayStyle
:
void main() async {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
runApp(new MaterialApp(
home: new Scaffold(),
));
}
如果您在一个脚手架中有应用栏,而在另一个脚手架中有 none,那就更棘手了。在那种情况下,我不得不在使用没有应用栏的脚手架推送新路线后调用 setSystemUIOverlayStyle
:
@override
Widget build(BuildContext context) {
final page = ModalRoute.of(context);
page.didPush().then((x) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
});
return new Scaffold();
}
我是 Whosebug 的新手,而且我从未使用过 Flutter,但我发现 this 包似乎让事情变得相对容易。
方法一:使用包
导入后,您需要做的就是添加以下代码片段:
try {
await FlutterStatusbarcolor.setStatusBarColor(Colors.black);
} on PlatformException catch (e) {
print(e);
}
替换 setStatusBarColor()
的参数应该会给您想要的结果,可以找到完整的颜色列表 here。
方法二:使用默认函数
如果这不起作用/您不想添加额外的包或库,那么
它涉及使用与上述方法类似的功能:getWindow().setStatusBarColor()
或getActivity().getWindow().setStatusBarColor()
用所需的十六进制代码替换参数 from the same list as earlier 也可能得到解决方案。
希望如此works/helps!
更新:
Scaffold(
appBar: AppBar(
systemOverlayStyle: SystemUiOverlayStyle(
systemNavigationBarColor: Colors.blue, // Navigation bar
statusBarColor: Colors.pink, // Status bar
),
),
)
旧的解决方案(仍然有效)
iOS和Android:
appBar: AppBar(
backgroundColor: Colors.red, // status bar and navigation bar color
brightness: Brightness.light, // status bar brightness
)
仅适用于 Android(更灵活)
您可以使用 SystemChrome
class 来更改状态栏和导航栏的颜色。
首先导入
import 'package:flutter/services.dart';
在此之后,您需要添加以下行(最好将这些行放在您的 main()
方法中)
void main() {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
systemNavigationBarColor: Colors.blue,
statusBarColor: Colors.pink,
));
}
我尝试了方法 SystemChrome.setSystemUIOverlayStyle()
,据我测试(Flutter SDK v1.9.1+hotfix.2,运行 on iOS 12.1)它非常适合 Android。但是对于 iOS,例如如果您的第一个屏幕 FirstScreen()
没有 AppBar
,但第二个屏幕 SecondScreen()
有,那么在启动时该方法会在 FirstScreen()
中设置颜色。但是,从 SecondScreen()
导航回 FirstScreen()
后,状态栏颜色变为透明。
我通过设置一个零高度的 AppBar()
想出了一个 hacky 解决方法,然后 AppBar 改变了状态栏的颜色,但 AppBar 本身是不可见的。希望对某人有用。
// FirstScreen that doesn't need an AppBar
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(0),
child: AppBar( // Here we create one to set status bar color
backgroundColor: Colors.black, // Set any color of status bar you want; or it defaults to your theme's primary color
)
)
);
}
// SecondScreen that does have an AppBar
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar()
}
}
这是 FirstScreen
在 iPhone Xs Max iOS 12.1 中的截图:
我做到了
@override
void initState() {
super.initState();
// Transparent status bar
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(statusBarColor: Colors.transparent,));
}
你也可以在逗号后看到不同的属性
SystemUiOverlayStyle(statusBarColor: Colors.transparent,)
只需在逗号后使用 ctrl + space 的组合,您就会得到您可以使用的内容。
请阅读这篇文章flutter package。要将状态栏文本设置为黑色,可以设置FlutterStatusbarcolor.setStatusBarWhiteForeground(false)
。你需要在 didChangeAppLifecycleState
方法中使用 resume state 这行代码,这样当你转到其他应用程序并返回时,状态栏文本颜色设置为你的初始颜色设置。
此外,您需要设置 AppBar 的 TextTheme。喜欢以下。
Widget build(BuildContext context) {
FlutterStatusbarcolor.setStatusBarWhiteForeground(false);
return MaterialApp(
title:// title goes here
theme:// your theme goes here
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
title: _loadAppBarTitle(),
textTheme: Theme.of(context).textTheme),
body: //body's goes here
);
);
希望这篇文章能帮到和我有类似问题的人。
TLDR; 您需要使用 Scaffold
,即使您来回导航,它也会管理颜色。
Scaffold(
appBar: AppBar(brightness: Brightness.dark), \ dark content -> white app bar
body: ...
);
如果您的屏幕没有应用栏,那么您需要使用AnnotatedRegion
和脚手架才能达到同样的效果。
AnnotatedRegion(
value: SystemUiOverlayStyle.light, // this will make the app bar white
child: Scaffold(
body:
),
);
而不是SystemUiOverlayStyle.light
,您可以自定义它:
SystemUiOverlayStyle(
statusBarBrightness: Brightness.light,
systemNavigationBarDividerColor: Colors.blue,
...
);
颤振 2.5.1
'brightness' is deprecated and shouldn't be used. This property is no longer used, please use systemOverlayStyle instead. This feature was deprecated after v2.4.0-0.0.pre.. Try replacing the use of the deprecated member with the replacement.
旧代码
brightness: Brightness.dark,
新密码
systemOverlayStyle: SystemUiOverlayStyle(
systemNavigationBarColor: Colors.blue, // Navigation bar
statusBarColor: Colors.red, // Status bar
),
把这段代码写在AppBar里面就可以了
Scaffold(
drawer: const SideBar(),
appBar: AppBar(
title: const Text("SomeThing"),
systemOverlayStyle: SystemUiOverlayStyle.dark,//this is what you wanted
),
body: YourWidget()