Make Flutter Status Bar Solid - flutter

My app doesn't use AppBar, and the content is overlapping with status bar when scrolled. I tried using AnnotatedRegion<SystemUiOverlayStyle>, however it doesn't change anything.
Overlapped
My best try is using SafeArea, however it turned Status Bar to grey.
Grey Safe Area
Is there a way to maintain the automatic color of status bar, without it overlapping with the content?
Additional Note:
Flutter 1.17.5
My Tree
SafeArea
|_ SingleChildScrollView
|_ Column
|_ Container
|_ Container
|_ Container
EDIT: I just realized the automatic color (status bar follow the first container's color) was because it was transparent. I was thinking of making it solid on runtime, and read it from the first colored widget.

import 'package:flutter/services.dart';
#override
Widget build(BuildContext context){
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle(
statusBarColor: Colors.blue, //or the color you prefer
),
child: SafeArea(child: Scaffold(...)),
);
}

You need to wrap your SafeArea widget with Container widget to change the color of the SafeArea widget
SAMPLE CODE
Scaffold(
backgroundColor: Colors.white,
body: Container(
color: Colors.red, /* Set your status bar color here */
child: SafeArea(
child: Container(
/* Add your Widget here */
)),
),
);
Another way You can use AppBar
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0.0,
backgroundColor: Colors.red,
),
body: Container(
child: //widget
)
);
}

Related

How to put any widget behind a bottom navigation bar Flutter

I am trying to put a text or container behind bottom Navigation Bar like pinterest bottom navigation
Container behind bottom navigation bar
#override
Widget build(BuildContext context) {
return Scaffold(
extendBody: true,
backgroundColor: Colors.red,
body: SafeArea(
child: Container(
height: 1000,
width: 200,
color: Colors.blue,
),
),
Add this to your Scaffold:
extendBody: true,

Set default icon theme to cupertino flutter appbar

The app that im building requires me to have an AppBar with a leading back button. However I prefer the cupertino back button(iOS-style) for the leading icon instead of the default back button for android. I am aware that I can manually change the leading button of each AppBar by using an iconButton but i was wondering if there is any easy way to do this like a theme. Any help appreciated.
Instead of using MaterialApp as your root widget you can use CupertinoApp to do the same, assuming that the above changing of the AppBar is needed for each screen in your app. This will automatically set the icon as you require
Here is a simple example to help you
Root Widget or starting point of the app
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return const CupertinoApp(
title: _title,
home: MyStatefulWidget(),
);
}
}
Then using a CupertinoPageScaffold where you want the CupertinoNavigationBar (I mean your appbar with ios icons) with the chevron icon like ios
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
// Try removing opacity to observe the lack of a blur effect and of sliding content.
automaticallyImplyLeading: true // This will decide if the leading icon comes in by default
backgroundColor: CupertinoColors.systemGrey.withOpacity(0.5),
middle: const Text('Sample Code'),
),
child: Column(
children: <Widget>[
Container(height: 50, color: CupertinoColors.systemRed),
Container(height: 50, color: CupertinoColors.systemGreen),
Container(height: 50, color: CupertinoColors.systemBlue),
Container(height: 50, color: CupertinoColors.systemYellow),
],
),
);
Facing a relatively similar problem I used the builder property, which it should work with any App like :
CupertinoApp(
builder: (_, child) => IconTheme(
data: IconThemeData(
size: 15,
color: const Color(0xffffffff),
),
child: child,
),
)
My problem was with the default icon color and size but you can use AppBarTheme or any similar widget to achieve what you want.
This may help you override default value with majority of the lacking theme delegates when working with the cupertino family (It's not yet mature like the material but I can see the constant and rapid effort and the future of it).

How to place a Progress bar over or inside an App Bar in Flutter?

Does anyone have any idea whether or not I can include a progress bar within an app bar? See screenshot of what I am trying to achieve. I am trying to reuse code and if I can create an App Bar with a Progress Indicator and then the same without. This will enable the users to complete this screen on signup and then EDIT this screen without the progress bar once they have an account. Is this even possible?
Your best option here is to use the 'bottom' property of the appBar widget it would look something like this
class HomeScreen extends StatelessWidget {
// this is to hide the progress inidecator once the account is created
bool isSignUpComplete = false;
#override
Widget build(BuildContext context) {
// this is to retrieve the device screen size
final Size size = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
bottom: !isSignUpComplete ? PreferredSize(
child: LinearProgressIndicator(
backgroundColor: Colors.red,
),
preferredSize: Size(size.width, 0),
) : null,
),
);
}
}
if you want to make a progress indicator in the app bar you can use the progress indicator in the title of the app bar but :
if you want to make it such as the image I will tell you how you can make a custom app bar below the progress indicator like this
class Myapplication extends StatelessWidget {
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Scaffold(
body: SafeArea(
child: Column(
children: [
LinearProgressIndicator(),
Row(
children: [
Icon(Icons.arrow_back_outlined, color: Colors.black),
],
),
],
),
),
);
}
}
I solved this by putting the progress bar in the body, extended the body behind the app bar and then made the app bar transparent.
class SignUpForm extends StatelessWidget {
double progress = 0.22;
#override
Widget build(BuildContext context) => Scaffold(
backgroundColor: Colors.white,
extendBodyBehindAppBar: true,
appBar: BasicFormAppBar(),
body: Column(
children: [
SizedBox(height: 45),
Container(
child: LinearProgressIndicator(
value: progress,
valueColor: AlwaysStoppedAnimation(Colors.Blue),
backgroundColor: Colors.Grey,
),
), //column & scaffold are not closed in this snippet

Remove AppBar but keeping StatusBar in Flutter

How I can have a custom color for my StatusBar without the AppBar?
To customize the StatusBar color I used this code:
appBar: AppBar(
backgroundColor: Colors.teal
)
If I remove appbar I can't customize the StatusBar. How I can do this?
How can I remove the AppBar but keeping the StatusBar?
Add this in your main.dart's main method file after the runApp method
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle(statusBarColor: <YOUR STATUS BAR COLOR>));
Like this:
void main(){
runApp(MyApp());
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle(statusBarColor: <YOUR STATUS BAR COLOR>));
}
If you are using SafeArea then you need to set it's top property to false.
You can also use this
#override
Widget build(BuildContext context) {
return Container(
color: Your Color Here,
child: SafeArea(
bottom: false,
child: Scaffold(
),
),
);
}
you can use the following code for change the status bar color first step you have to import this package given below
"import 'package:flutter/services.dart';
and then add this code in your main.dart file
void main(){SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(statusBarColor:Colors.blue,));}
Simply we can implemet using AppBar, in below code backgroundColor: Colors.green is applied to statusbar.
Scaffold(
appBar: AppBar(
systemOverlayStyle: SystemUiOverlayStyle.dark,
backgroundColor: Colors.green,
elevation: 0,
toolbarHeight: 0,
),
backgroundColor: Colors.white38,
body: Container(),
)
Prview:

Flutter - System bar colors with SafeArea

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,
),
);
}
This is what I see
If I wrap SafeArea inside a Container with color property set to white, it works but system bar icons also turn white
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.
Container(
color ...
),
child: SafeArea(
child: Scaffold(
body:
AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.light,
child: ...
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:
Don't wrap Scaffolds into SafeAreas;
[iOS] paint your Scaffold the right Color;
[Android] set the System Bars programmatically.
1. Proper use of 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(),
),
);
2. iOS Notch
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(),
),
);
3. Android SystemUI
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.
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!
Replace your Overlay style with below code it will work
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle.dark.copyWith(statusBarColor: Colors.white));
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,
))),
],
)
]),
)),
)
),
);
}
}