Reputation: 17787
I am trying to add SafeArea
widget for the flutter app with colorized system bars but somehow they are always turning black.
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle.light.copyWith(
systemNavigationBarIconBrightness: Brightness.dark,
systemNavigationBarColor: kSurfaceColor,
statusBarIconBrightness: Brightness.dark,
statusBarColor: Colors.red, // Note RED here
),
);
return SafeArea(
child: Scaffold(
backgroundColor: kWhiteColor,
appBar: _buildAppBar(context), // Title and Avatar are built here
body: _buildBody(), // This function just returns blank Container for now
floatingActionButton: _buildFAB(context),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
),
);
}
If I wrap SafeArea
inside a Container
with color
property set to white, it works but system bar icons also turn white
Upvotes: 18
Views: 21358
Reputation: 541
set only main class
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle.light.copyWith(
systemNavigationBarIconBrightness: Brightness.dark,
systemNavigationBarColor: Colors.white,
statusBarIconBrightness: Brightness.light,
statusBarColor: HexColor(HexColor.primarycolor), // Note RED here
),
);
my Example code
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:loader_overlay/loader_overlay.dart';
import 'HexColor.dart';
class CityListActiviy extends StatefulWidget {
// Initially password is obscure
@override
State<CityListActiviy> createState() => _CityListActiviyState();
}
class _CityListActiviyState extends State<CityListActiviy> {
TextEditingController userid_Controller = new TextEditingController();
bool userid_validate = false;
final String requiredNumber = '123456';
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle.light.copyWith(
systemNavigationBarIconBrightness: Brightness.dark,
systemNavigationBarColor: Colors.white,
statusBarIconBrightness: Brightness.light,
statusBarColor: HexColor(HexColor.primarycolor), // Note RED here
),
);
return MaterialApp(
debugShowCheckedModeBanner: true,
home: LoaderOverlay(
child:SafeArea(
child: Scaffold(
backgroundColor: HexColor(HexColor.gray_activity_background),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Stack(
children: [
Container(
height: 60,
padding: new EdgeInsets.all(20.0),
decoration: BoxDecoration(
color: HexColor(HexColor.white),
),
width: MediaQuery.of(context).size.width,
child: Text("Select Your Location",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
color: Colors.grey,
fontFamily: 'montserrat_medium',
decoration: TextDecoration.none,
))),
],
)
]),
)),
)
),
);
}
}
Upvotes: 0
Reputation: 2097
I know this is an old question, but after reading the documentation I came up with a more complete solution.
My answer considers the following:
SafeArea
SafeArea
is a widget that performs a MediaQuery
to add some proper padding to your application. This should happen inside the body
of your Scaffold
application. Something like this will lead to code that won't unexpectedly break later on:
return Scaffold(
// ...
body: SafeArea( // your SafeArea should stay here
child: YourWidget(),
),
);
As other answers said already, you just have to paint your Scaffold so that you'll get the color you want. Your Scaffold should include a backgroundColor
property (and your AppBar too, if you have one).
return Scaffold(
// ...
backgroundColor: yourColor, // the RED you need
appBar: AppBar( // if any
backgroundColor: yourColor, // maybe RED here, also
// a system overlay option is included here, too, see 3.
// ...
),
body: SafeArea( // your SafeArea should stay here
child: YourWidget(),
),
);
As OP did, you need SystemChrome.setSystemUIOverlayStyle()
to address Android-related system bar paints.
However, the documentation says that this method should be called programmatically whenever a new page / a new route is being popped or pushed, if you have different Route
colors.
Suppose you have a 2.0 Router
; then, you would write its build
method as it follows:
Widget build(BuildContext context) {
Color overlayColor = ... your color ...;
final systemBarColors = SystemUiOverlayStyle(
systemNavigationBarColor: overlayColor,
statusBarColor: overlayColor,
);
SystemChrome.setSystemUIOverlayStyle(systemBarColors);
return AnnotatedRegion<SystemUiOverlayStyle>(
value: systemBarColors,
child: Navigator(
key: navigatorKey,
pages: _stack,
onPopPage: _onPopPage,
),
);
}
This will ensure that every time a new page is popped or pushed, i.e. the build
method of our Router
is called, the Android system bar and status bar are properly painted.
Upvotes: 9
Reputation: 463
Replace your Overlay style with below code it will work
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle.dark.copyWith(statusBarColor: Colors.white));
Upvotes: 3
Reputation: 525
For your case just wrapping SafeArea()
to the top widget that will be DISPLAYED on the screen(example: your 'Today' text widget) should avoid the black color on system bar.
Full example.
Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SafeArea(
child: Text('Today'),
),
Text('Tomorrow')
]
);
This worked for me!
Upvotes: 1
Reputation: 1167
Building on @david-carrilho's answer, I created this simple widget
import 'package:flutter/material.dart';
class ColoredSafeArea extends StatelessWidget {
final Widget child;
final Color color;
const ColoredSafeArea({Key key, @required this.child, this.color})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: color ?? Theme.of(context).colorScheme.primaryVariant,
child: SafeArea(
child: child,
),
);
}
}
Then wherever I would use a SafeArea
, I use my little wrapper widget ColoredSafeArea
.
class MyExampleView extends StatelessWidget {
const MyExampleView({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ColoredSafeArea(
child: Center(
child: Text('Nice color bar'),
),
);
}
}
The reason why this works is because it creates a container behind your content with the specified color, then SafeArea
simply adds the necessary padding based on the device.
Upvotes: 16
Reputation: 55
Container(
color ...
),
child: SafeArea(
child: Scaffold(
body:
AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.light,
child: ...
Upvotes: 3