Как изменить статус и цвет навигационной панели в Flutter?
Я пытаюсь изменить цвет строки состояния системы на черный. Конфигурация, похоже, переопределена классом AppBar. Я могу добиться того, чего хочу, назначив тему: для ThemeData.dark()
при создании Material App, а затем указав appBar attribute
. Но я не хочу AppBar, а также, делая это таким образом, меняет все цвета шрифтов.
Возможное решение - наследовать ThemeData.bright() в новый класс, а затем добавить что-то, что только изменяет строку состояния системы через
setSystemUIOverlayStyle
И тогда мне нужно будет указать AppBar и сделать его невидимым каким-то образом?
https://docs.flutter.io/flutter/services/SystemChrome/setSystemUIOverlayStyle.html
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 itemBuilder 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'),
]));
Ответы
Ответ 1
Вы можете использовать класс SystemChrome
для изменения строки состояния и цвета панели навигации. Первый импорт
import 'package:flutter/services.dart';
После этого вам нужно добавить следующие строки (лучшее место для размещения этих строк в вашем методе main()
)
void main() {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
systemNavigationBarColor: Colors.blue,
statusBarColor: Colors.pink,
));
}
Ответ 2
Если вы вообще не хотите AppBar, вы можете просто вызвать setSystemUIOverlayStyle
в основной функции:
void main() async {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
runApp(new MaterialApp(
home: new Scaffold(),
));
}
Это более сложно, если у вас есть панель приложений на одном эшафоте, а в другом нет. В этом случае мне пришлось вызвать setSystemUIOverlayStyle
после нажатия нового маршрута с помощью эшафот, у которого нет панели приложений:
@override
Widget build(BuildContext context) {
final page = ModalRoute.of(context);
page.didPush().then((x) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
});
return new Scaffold();
}
Ответ 3
Я совершенно новый для StackOverflow, и я никогда не использовал Flutter, однако я нашел этот пакет, который, похоже, делает вещи относительно легкими.
Способ 1. Использование пакета
После импорта все, что вам нужно сделать, это добавить этот фрагмент кода:
try {
await FlutterStatusbarcolor.setStatusBarColor(Colors.black);
} on PlatformException catch (e) {
print(e);
}
Замена параметра setStatusBarColor()
должна дать вам желаемый результат, полный список цветов можно найти здесь.
Способ 2. Использование функций по умолчанию
Если это не работает/вы не хотите добавлять дополнительные пакеты или библиотеки, возможно, этот ответ может помочь.
Он включает использование аналогичной функции для вышеуказанного метода: getWindow().setStatusBarColor()
или getActivity().getWindow().setStatusBarColor()
Замена параметра желаемым шестнадцатеричным кодом из того же списка, что и раньше, может также привести к решению.
Надеюсь, он работает/помогает!
Ответ 4
Я попробовал метод SystemChrome.setSystemUIOverlayStyle()
, насколько я тестировал (Flutter SDK v1.9.1 + hotfix.2, работает на iOS 12.1), он отлично работает для Android. Но для iOS, например если ваш первый экран FirstScreen()
не имеет AppBar
, а второй SecondScreen()
, то при запуске метод устанавливает цвет в FirstScreen()
. Однако после перехода назад к FirstScreen()
из SecondScreen()
цвет строки состояния становится прозрачным.
Я придумала хакерский обходной путь, установив AppBar()
с нулевой высотой, затем цвет строки состояния изменяется AppBar, но сама AppBar не видна. Надеюсь, это кому-нибудь пригодится.
// FirstScreen that does not 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 primary color
)
)
);
}
// SecondScreen that does have an AppBar
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar()
}
}
Вот скриншот FirstScreen
в iPhone Xs Max iOS 12.1: