Related
I recently tried keeping a Hamburger icon for my menu slider without an AppBar or at least completely invisible. The first attempt was with a SafeArea but that emptied Scaffold. Then I tried setting the Opacity to 0.0 like shown on the code below. But it gives out the same result as SafeArea with nothing on Scaffold. Please can anyone help?
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return new MaterialApp(
theme: ThemeData(
// Define the default Brightness and Colors
brightness: Brightness.dark,
primaryColor: Colors.lightBlue[800],
accentColor: Colors.cyan[600],
),
home: Scaffold(
Opacity(
opacity: 0.0,
appBar: AppBar(),
),
drawer: new Drawer(
child: new ListView(),
),
body: new Center(
child: new Column(
children: <Widget>[],
))),
);
}
}
If I have understood you well, you want to display a menu button to show the Drawer without displaying any AppBar.
One option is to use a Stack for the body of the Scaffold.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
var scaffoldKey = GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
return new MaterialApp(
theme: ThemeData(
// Define the default Brightness and Colors
brightness: Brightness.dark,
primaryColor: Colors.lightBlue[800],
accentColor: Colors.cyan[600],
),
home: Scaffold(
key: scaffoldKey,
drawer: new Drawer(
child: new ListView(),
),
body: Stack(
children: <Widget>[
new Center(
child: new Column(
children: <Widget>[],
)),
Positioned(
left: 10,
top: 20,
child: IconButton(
icon: Icon(Icons.menu),
onPressed: () => scaffoldKey.currentState.openDrawer(),
),
),
],
),
),
);
}
}
If I have understood your question well.
You have your own custom Menu button to open/close drawer.
You don't want to use AppBar as well.
In that case you can use GlobalKey<ScaffoldState>() object to open Drawer.
import 'package:flutter/material.dart';
GlobalKey<ScaffoldState> _scaffoldState = GlobalKey<ScaffoldState>();
return Scaffold(
key: _scaffoldState,
drawer: DrawerView(),
body: ThemeScreen(
header: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
IconButton(
icon: Icon(Icons.menu,
color: Colors.white,
size: 15),
onPressed: (){
_scaffoldState.currentState.openDrawer();
},
),
],
),
),
);
You can make AppBar completely invisible by setting the same color and elevation = 0
screenshot here
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFF198BAA),
appBar: AppBar(
backgroundColor: Color(0xFF198BAA),
elevation: 0.0,
),
drawer: Drawer(
child: SafeArea(
child: Padding(
padding: const EdgeInsets.all(18.0),
child: ListView(
children: <Widget>[
ListTile(
title: Text('Item1'),
)
],
),
),
),
),
);
}
}
This is similar to Ox.S's answer, but you can make the AppBar transparent and then change the icon to whatever color you want.
Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0.0,
iconTheme: IconThemeData(color: Colors.black),
),
drawer: Drawer(...
I had followed the hero animation tutorial in flutter. When i tried to add one more sceen i just noticed that the timedilation property is affecting the loading time of other screens also. And I had tried resetting the variable to zero but it didn't work as expected.
class PhotoHero extends StatelessWidget {
const PhotoHero({Key key, this.photo, this.onTap, this.width})
: super(key: key);
final String photo;
final VoidCallback onTap;
final double width;
Widget build(BuildContext context) {
return SizedBox(
width: width,
child: Hero(
tag: photo,
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: onTap,
child: Image.asset(
photo,
fit: BoxFit.contain,
),
),
),
),
); }}
class HeroAnimation extends StatelessWidget {
Widget build(BuildContext context) {
timeDilation = 10.0; // 1.0 means normal animation speed.
return Scaffold(
appBar: AppBar(
title: const Text('Basic Hero Animation'),
),
body: Center(
child: PhotoHero(
photo: 'images/flippers-alpha.png',
width: 300.0,
onTap: () {
Navigator.of(context).push(
MaterialPageRoute<void>(builder: (context) => SecondScreen()));
},
),
),
); }}
void main() {
runApp(MaterialApp(
routes: {
'/': (context) => HeroAnimation(),
'/second': (context) => SecondScreen(),
'/third': (context) => ThirdScreen(),
}, ));}
class ThirdScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Title(color: Colors.red, child: Text('Dummy Title')),
),
); }}
class SecondScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flippers Page'),
),
body: Container(
// Set background to blue to emphasize that it's a new route.
color: Colors.lightBlueAccent,
padding: const EdgeInsets.all(16.0),
alignment: Alignment.topLeft,
child: PhotoHero(
photo: 'images/flippers-alpha.png',
width: 100.0,
onTap: () {
Navigator.of(context).pushNamed('/third');
},
),
),
); }}
This is expected as timeDilation is global property sort of , so you need to set it every time you need to change the speed of your animation onTap will be perfect place to do so,
check the modified code below
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
class PhotoHero extends StatelessWidget {
const PhotoHero({Key key, this.photo, this.onTap, this.width})
: super(key: key);
final String photo;
final VoidCallback onTap;
final double width;
Widget build(BuildContext context) {
return SizedBox(
width: width,
child: Hero(
tag: photo,
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: onTap,
child: Image.asset(
photo,
fit: BoxFit.contain,
),
),
),
),
); }}
class HeroAnimation extends StatelessWidget {
Widget build(BuildContext context) {
//timeDilation = 10.0; // 1.0 means normal animation speed.
return Scaffold(
appBar: AppBar(
title: const Text('Basic Hero Animation'),
),
body: Center(
child: PhotoHero(
photo: '/images/flippers-alpha.png',
width: 300.0,
onTap: () {
timeDilation = 10.0;
Navigator.of(context).push(
MaterialPageRoute<void>(builder: (context) => SecondScreen()));
},
),
),
); }}
void main() {
runApp(MaterialApp(
routes: {
'/': (context) => HeroAnimation(),
'/second': (context) => SecondScreen(),
'/third': (context) => ThirdScreen(),
}, ));}
class ThirdScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
timeDilation = 1.0;
return Scaffold(
appBar: AppBar(
title: Title(color: Colors.red, child: Text('Dummy Title')),
),
); }}
class SecondScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
//timeDilation = 1.0;
return Scaffold(
appBar: AppBar(
title: const Text('Flippers Page'),
),
body: Container(
// Set background to blue to emphasize that it's a new route.
color: Colors.lightBlueAccent,
padding: const EdgeInsets.all(16.0),
alignment: Alignment.topLeft,
child: PhotoHero(
photo: '/images/flippers-alpha.png',
width: 100.0,
onTap: () {
Navigator.of(context).pushNamed('/third');
},
),
),
); }}
If you add timeDilation it will affect the other screens animation time. Because it's a global property. In order to go back to the normal animation speed you have to change that variable value to 1.0 which is the normal animation speed.
class FirstScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
timeDilation = 8.0; // Since we need the animation to slow down.
}
class SecondScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
timeDilation = 1.0; // Changing the value to normal animation speed.
}
As a note, if you are coming back using back button the build method won't get called so the timeDilation value won't change to the value of the screen which you're in. In this case you've to make your screen as StatefulWidget then you can set the value on the life cycle methods.
I am trying to change the status bar color to white. I found this pub on flutter. I tried to use the example code on my dart files.
Update Flutter 2.0 (Recommended):
On latest Flutter version, you should use:
AppBar(
systemOverlayStyle: SystemUiOverlayStyle(
// Status bar color
statusBarColor: Colors.red,
// Status bar brightness (optional)
statusBarIconBrightness: Brightness.dark, // For Android (dark icons)
statusBarBrightness: Brightness.light, // For iOS (dark icons)
),
)
Only Android (more flexibility):
import 'package:flutter/services.dart';
void main() {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
systemNavigationBarColor: Colors.blue, // navigation bar color
statusBarColor: Colors.pink, // status bar color
));
}
Both iOS and Android:
appBar: AppBar(
backgroundColor: Colors.red, // Status bar color
)
A bit hacky but works on both iOS and Android:
Container(
color: Colors.red, // Status bar color
child: SafeArea(
left: false,
right: false,
bottom: false,
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue, // App bar color
),
),
),
)
Works totally fine in my app
import 'package:flutter_statusbarcolor/flutter_statusbarcolor.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
FlutterStatusbarcolor.setStatusBarColor(Colors.white);
return MaterialApp(
title: app_title,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(title: home_title),
);
}
}
(this package)
UPD:
Recommended solution (Flutter 2.0 and above)
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.white
));
For those who uses AppBar
If you use AppBar then updating status bar color is as simple as this:
Scaffold(
appBar: AppBar(
// Use [Brightness.light] for black status bar
// or [Brightness.dark] for white status bar
// https://stackoverflow.com/a/58132007/1321917
brightness: Brightness.light
),
body: ...
)
To apply for all app bars:
return MaterialApp(
theme: Theme.of(context).copyWith(
appBarTheme: Theme.of(context)
.appBarTheme
.copyWith(brightness: Brightness.light),
...
),
For those who don't use AppBar
Wrap your content with AnnotatedRegion and set value to SystemUiOverlayStyle.light or SystemUiOverlayStyle.dark:
return AnnotatedRegion<SystemUiOverlayStyle>(
// Use [SystemUiOverlayStyle.light] for white status bar
// or [SystemUiOverlayStyle.dark] for black status bar
// https://stackoverflow.com/a/58132007/1321917
value: SystemUiOverlayStyle.light,
child: Scaffold(...),
);
Edit for Flutter 2.0.0
The answer below does not work anymore when you have an AppBar on the screen. You now need to configure the AppBarTheme.brightness and AppBarTheme.systemOverlayStyle correctly in that case.
Answer
Instead of the often suggested SystemChrome.setSystemUIOverlayStyle() which is a system wide service and does not reset on a different route, you can use an AnnotatedRegion<SystemUiOverlayStyle> which is a widget and only has effect for the widget that you wrap.
AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle(
statusBarColor: Colors.white,
),
child: Scaffold(
...
),
)
This worked for me:
Import Service
import 'package:flutter/services.dart';
Then add:
#override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.white,
statusBarBrightness: Brightness.dark,
));
return MaterialApp(home: Scaffold(
Change status bar color when you are not using AppBar
First Import this
import 'package:flutter/services.dart';
Now use below code to change status bar color in your application when you are not using the AppBar
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark.copyWith(
statusBarColor: AppColors.statusBarColor,/* set Status bar color in Android devices. */
statusBarIconBrightness: Brightness.dark,/* set Status bar icons color in Android devices.*/
statusBarBrightness: Brightness.dark)/* set Status bar icon color in iOS. */
);
To change the status bar color in iOS when you are using SafeArea
Scaffold(
body: Container(
color: Colors.red, /* Set your status bar color here */
child: SafeArea(child: Container(
/* Add your Widget here */
)),
),
);
I think this will help you:
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
systemNavigationBarColor: Colors.white, // navigation bar color
statusBarColor: Colors.white, // status bar color
statusBarIconBrightness: Brightness.dark, // status bar icons' color
systemNavigationBarIconBrightness: Brightness.dark, //navigation bar icons' color
));
What worked for me (For those who don't use AppBar)
Add AppbBar with preferred color and then set : toolbarHeight: 0
child: Scaffold(
appBar: AppBar(
toolbarHeight: 0,
backgroundColor: Colors.blue,
brightness: Brightness.light,
)
I can't comment directly in the thread since I don't have the requisite reputation yet, but the author asked the following:
the only issue is that the background is white but the clock, wireless and other text and icons are also in white .. I am not sure why!!
For anyone else who comes to this thread, here's what worked for me. The text color of the status bar is decided by the Brightness constant in flutter/material.dart. To change this, adjust the SystemChrome solution like so to configure the text:
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.red,
statusBarBrightness: Brightness.dark,
));
Your possible values for Brightness are Brightness.dark and Brightness.light.
Documentation:
https://api.flutter.dev/flutter/dart-ui/Brightness-class.html
https://api.flutter.dev/flutter/services/SystemUiOverlayStyle-class.html
This is everything you need to know:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
systemNavigationBarColor: Colors.amber, // navigation bar color
statusBarColor: Colors.white, // status bar color
statusBarIconBrightness: Brightness.dark, // status bar icon color
systemNavigationBarIconBrightness: Brightness.dark, // color of navigation controls
));
runApp(MyApp());
}
It can be achieved in 2 steps:
Set the status bar color to match to your page background using FlutterStatusbarcolor package
Set the status bar buttons' (battery, wifi etc.) colors using the AppBar.brightness property
If you have an AppBar:
#override
Widget build(BuildContext context) {
FlutterStatusbarcolor.setStatusBarColor(Colors.white);
return Scaffold(
appBar: AppBar(
brightness: Brightness.light,
// Other AppBar properties
),
body: Container()
);
}
If you don't want to show the app bar in the page:
#override
Widget build(BuildContext context) {
FlutterStatusbarcolor.setStatusBarColor(Colors.white);
return Scaffold(
appBar: AppBar(
brightness: Brightness.light,
elevation: 0.0,
toolbarHeight: 0.0, // Hide the AppBar
),
body: Container()
}
[Tested in Android]
This is how I was able to make status bar transparent and it's text color dark,
import 'package:flutter/services.dart';
void main() {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.transparent, // transparent status bar
statusBarIconBrightness: Brightness.dark // dark text for status bar
));
runApp(MyApp());
}
Using AnnotatedRegion is what works best for me, especially if I don't have an AppBar
import 'package:flutter/services.dart';
...
Widget build(BuildContext context) {
return Scaffold(
body: AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.light,
child: ...,
),
);
}
From Flutter 2.5.0
brightness property is deprecated in AppBar
We need to use, systemOverlayStyle property
Example,If you are using an AppBar
AppBar(
title: Text("Title"),
systemOverlayStyle: SystemUiOverlayStyle.dark) //for dark color
on the main.dart file
import service like follow
import 'package:flutter/services.dart';
and inside build method just add this line before return
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.orange
));
Like this:
#override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: CustomColors.appbarcolor
));
return MaterialApp(
home: MySplash(),
theme: ThemeData(
brightness: Brightness.light,
primaryColor: CustomColors.appbarcolor,
),
);
}
This one will also work
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
This is by far is the best way, it requires no extra plugins.
Widget emptyAppBar(){
return PreferredSize(
preferredSize: Size.fromHeight(0.0),
child: AppBar(
backgroundColor: Color(0xFFf7f7f7),
brightness: Brightness.light,
)
);
}
and call it in your scaffold like this
return Scaffold(
appBar: emptyAppBar(),
.
.
.
Most of the answers are using SystemChrome which only works for Android. My solution is to combine both AnnotatedRegion and SafeArea into new Widget so it also works in iOS. And I can use it with or without AppBar.
class ColoredStatusBar extends StatelessWidget {
const ColoredStatusBar({
Key key,
this.color,
this.child,
this.brightness = Brightness.dark,
}) : super(key: key);
final Color color;
final Widget child;
final Brightness brightness;
#override
Widget build(BuildContext context) {
final defaultColor = Colors.blue;
final androidIconBrightness =
brightness == Brightness.dark ? Brightness.light : Brightness.dark;
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle(
statusBarColor: color ?? defaultColor,
statusBarIconBrightness: androidIconBrightness,
statusBarBrightness: brightness,
),
child: Container(
color: color ?? defaultColor,
child: SafeArea(
bottom: false,
child: Container(
child: child,
),
),
),
);
}
}
Usage: Place it to top of page's widget.
#override
Widget build(BuildContext context) {
return ColoredStatusBar(
child: /* your child here */,
);
}
None of the answers seem to mention that you can do it with your ThemeData function in your main MaterialApp widget.
return MaterialApp(
theme: ThemeData(
appBarTheme: const AppBarTheme(
systemOverlayStyle: SystemUiOverlayStyle(
statusBarColor: Colors.white,
),
),
),
),
This can also be done in the darkTheme ThemeData.
Latest solution. Flutter 2.0 and above
For those who use AppBar:
/// WORKS on the screen where appBar is used
Scaffold(
appBar: AppBar(
systemOverlayStyle: SystemUiOverlayStyle(
// statusBarColor: Colors.red, // You can use this as well
statusBarIconBrightness: Brightness.dark, // OR Vice Versa for ThemeMode.dark
statusBarBrightness: Brightness.light, // OR Vice Versa for ThemeMode.dark
),
),
),
For those who DON'T use AppBar:
Put the code below on the root screen's build function to AFFECT all the screens below:
void main() {
runApp(MyApp());
}
// This widget is the root of your application.
class MyApp extends StatelessWidget {
/// WORKS on every screen EXCEPT the screen in which appBar is used
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle(
// statusBarColor: Colors.red, // You can use this as well
statusBarIconBrightness: Brightness.dark, // OR Vice Versa for ThemeMode.dark
statusBarBrightness: Brightness.light, // OR Vice Versa for ThemeMode.dark
),
);
#override
Widget build(BuildContext context) {}
}
Put the code below on the single screen's build function to AFFECT this screen only:
class SingleScreen extends StatelessWidget {
/// WORKS on a single screen where appBar is NOT used
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle(
// statusBarColor: Colors.red, // You can use this as well
statusBarIconBrightness: Brightness.dark, // OR Vice Versa for ThemeMode.dark
statusBarBrightness: Brightness.light, // OR Vice Versa for ThemeMode.dark
),
);
#override
Widget build(BuildContext context) {}
}
return Scaffold(
backgroundColor: STATUS_BAR_COLOR_HERE,
body: SafeArea(
child: scaffoldBody(),
),
);
Works for both iOS and Android
import 'package:flutter/services.dart';
#override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);
return Scaffold();
}
You can do as follows,
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle(
statusBarColor: Colors.grey.withOpacity(0.5),
statusBarIconBrightness: Brightness.dark,
statusBarBrightness:
Platform.isAndroid ? Brightness.dark : Brightness.light,
systemNavigationBarColor: Colors.white,
systemNavigationBarDividerColor: Colors.grey,
systemNavigationBarIconBrightness: Brightness.dark,
),
);
Add this code to your main.dart build method,
this (inside the scaffold) creates a black statusbar with light content. (no Appbar)
appBar: AppBar(
toolbarHeight: 0,
backgroundColor: Colors.black,
systemOverlayStyle: SystemUiOverlayStyle.light,
),
to Make it Like your App Bar Color
import 'package:flutter/material.dart';
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
systemNavigationBarColor: Colors.transparent,
));
}
None of the existing solutions helped me, because I don't use AppBar and I don't want to make statements whenever the user switches the app theme. I needed a reactive way to switch between the light and dark modes and found that AppBar uses a widget called Semantics for setting the status bar color.
Basically, this is how I do it:
return Semantics(
container: false, // don't make it a new node in the hierarchy
child: AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.light, // or .dark
child: MyApp(), // your widget goes here
),
);
Semantics is imported from package:flutter/material.dart.
SystemUiOverlayStyle is imported from package:flutter/services.dart.
Use this way to make your status bar completely white with the dark status bar icons,
I use it personally! tested on android worked fine!
import 'package:FileSharing/bodypage.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
appBarTheme: AppBarTheme(
color: Colors.white,
elevation: 0,
brightness: Brightness.light,
centerTitle: true,
iconTheme: IconThemeData(
color: Colors.black,
),
textTheme: TextTheme(),
)
// This makes the visual density adapt to the platform that you run
// the app on. For desktop platforms, the controls will be smaller and
// closer together (more dense) than on mobile platforms.
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.white,
));
return Scaffold(
appBar: AppBar(
brightness: Brightness.light,
actions: [
Container(
width: 63,
padding: EdgeInsets.only(right: 30),
child: FloatingActionButton(
onPressed: null,
backgroundColor: Colors.pink,
elevation: 8,
child: Icon(Icons.person_pin),
),
)
],
),
);
}
}
The best way with out any packages
Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
toolbarHeight: 0,
backgroundColor: Colors.transparent,
elevation: 0,
systemOverlayStyle: const SystemUiOverlayStyle(
statusBarColor: Colors.transparent, // <-- SEE HERE
statusBarIconBrightness:
Brightness.dark, //<-- For Android SEE HERE (dark icons)
statusBarBrightness: Brightness.light,
),
),.......
you can use for Android:
import 'package:flutter/services.dart';
void main() {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
systemNavigationBarColor: Colors.blue, // navigation bar color
statusBarColor: Colors.pink, // status bar color
));
}
you can also use this in SliverAppBar, don't forget to use backwardsCompatibility: false it would not work if you skip this property. also see doc
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: null,
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
systemOverlayStyle: SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.dark),
backwardsCompatibility: false,
//... remaining code and close braces..
I am trying to set a common theme for app so I need to change appbar color as a color that indicates hex code #0f0a1a
const MaterialColor toolbarColor = const MaterialColor(
0xFF151026, const <int, Color>{0: const Color(0xFF151026)});
I try this piece of code to make a custom color but fails.
How can I do this from themeData?
Declare your Color:
const primaryColor = Color(0xFF151026);
In the MaterialApp level (will change the AppBar Color in the whole app ) change primaryColor
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primaryColor: primaryColor,
),
home: MyApp(),
);
and if you want to change it on the Widget level modify the backgroundColor
appBar: AppBar(
backgroundColor: primaryColor,
),
If you don't want to change the whole PrimaryColor you can also define AppBarTheme in your ThemeData:
MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
appBarTheme: AppBarTheme(
color: const Color(0xFF151026),
)),
home: myApp(),
)
In the current version of Flutter, to comply with the new "Material You" design, we should try to use ColorScheme whenever possible. The app bar color is controlled by:
If theme brightness is light, use primary color.
If theme brightness is dark, use surface color.
For examples:
Light Mode
Set brightness to light, then set primary and onPrimary to yellow and black, and set all other colors to grey to showcase that they are not relevant to AppBar:
MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme(
brightness: Brightness.light,
primary: Colors.yellow,
onPrimary: Colors.black,
// Colors that are not relevant to AppBar in LIGHT mode:
primaryVariant: Colors.grey,
secondary: Colors.grey,
secondaryVariant: Colors.grey,
onSecondary: Colors.grey,
background: Colors.grey,
onBackground: Colors.grey,
surface: Colors.grey,
onSurface: Colors.grey,
error: Colors.grey,
onError: Colors.grey,
),
),
home: Scaffold(
appBar: AppBar(title: Text("Light Mode Demo")),
),
)
Dark Mode
Set brightness to dark, then set surface and onSurface to yellow and black, all others to grey to showcase that they are not relevant to AppBar.
MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme(
brightness: Brightness.dark,
surface: Colors.yellow,
onSurface: Colors.black,
// Colors that are not relevant to AppBar in DARK mode:
primary: Colors.grey,
onPrimary: Colors.grey,
primaryVariant: Colors.grey,
secondary: Colors.grey,
secondaryVariant: Colors.grey,
onSecondary: Colors.grey,
background: Colors.grey,
onBackground: Colors.grey,
error: Colors.grey,
onError: Colors.grey,
),
),
home: Scaffold(
appBar: AppBar(title: Text("Dark Mode Demo")),
),
)
include backgroundColor: to appbar
appBar: AppBar(
title: const Text('Example'),
backgroundColor: Colors.black,
),
With the new Material 3 and Flutter 3 updates, background color for AppBar can be changed using surfaceTintColor.
Either inside the AppBar like this:
return AppBar(
...
surfaceTintColor: backgroundColor ?? CommonColors.lightColor,
);
Or inside the ThemeData class like this:
ThemeData.light().copyWith(
...
appBarTheme: AppBarTheme(
backgroundColor: CommonColors.lightColor,
surfaceTintColor: CommonColors.lightColor,
actionsIconTheme: const IconThemeData(color: Colors.white),
),
),
According to AppBar description On Flutter 2.5, it uses ColorScheme.primary by default.
The default app bar [backgroundColor] is the overall theme's
[ColorScheme.primary] if the overall theme's brightness is [Brightness.light]. Unfortunately this is the same as the default
[ButtonStyle.foregroundColor] for [TextButton] for light themes.
In this case a preferable text button foreground color is
[ColorScheme.onPrimary], a color that contrasts nicely with
[ColorScheme.primary]. to remedy the problem, override
[TextButton.style]:
try using colorScheme
MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSwatch(
primarySwatch: const Color(0xFF151026),
),
),
home: MyApp(),
),
And to use somewhere else
Theme.of(context).colorScheme.primary,
Or you can just call backgroundColor on Appbar.
For more, visit ThemeData-class
To change Appbar backgroundColor in the whole app:
MaterialApp(theme: ThemeData(appBarTheme: AppBarTheme(backgroundColor: Colors.blueGrey),),);
You can use Flutter ThemeData,if you want to set a theme for your entire application:
class HomePage extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MyApp',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'MyApp',),
);
}
}....
Then if you want to change certain elements of your primary and secondary colors,you can achieve this using the colorScheme from Swatch.
Learn More Here
Here is an example using colorScheme :
class HomePage extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MyApp',
theme: ThemeData(
colorScheme: ColorScheme.fromSwatch(
primarySwatch: Colors.blue,//the color of your Appbar will be blue
).copyWith(
secondary: Colors.green,
//your accent color-floating action will appear green
),
),
home: MyHomePage(title: 'MyApp',),
);
Since flutter 2.5+, the working solution will be simply use ColorScheme in ThemeData:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: const AppBarWidget(),
theme: ThemeData.light().copyWith(
colorScheme: ColorScheme.fromSwatch().copyWith(
// change the appbar color
primary: Colors.green[800],
),
),
);
}
}
class AppBarWidget extends StatelessWidget {
const AppBarWidget({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('AppBar'),
),
);
}
}
If you are using material 3. you have to take care of tint and forground color also.
Scaffold(
appBar: AppBar(
backgroundColor: Colors.white //your color,
surfaceTintColor: Colors.white // for material 3 you have to make it transparent,
)
For the background color, you can use backgroundColor property, for the text color you can apply a style.
Example:
class MyHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Jorgesys', style: TextStyle(color: Colors.cyanAccent),),
backgroundColor: Colors.green, //App Bar background color.
),
body: Column(
...
...
How can I simply set the height of the AppBar in Flutter?
The title of the bar should be staying centered vertically (in that AppBar).
You can use PreferredSize:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Example',
home: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(50.0), // here the desired height
child: AppBar(
// ...
)
),
body: // ...
)
);
}
}
Use toolbarHeight:
There's no longer a need to use PreferredSize. Use toolbarHeight with flexibleSpace.
AppBar(
toolbarHeight: 120, // Set this height
flexibleSpace: Container(
color: Colors.orange,
child: Column(
children: [
Text('1'),
Text('2'),
Text('3'),
Text('4'),
],
),
),
)
You can use PreferredSize and flexibleSpace for it:
appBar: PreferredSize(
preferredSize: Size.fromHeight(100.0),
child: AppBar(
automaticallyImplyLeading: false, // hides leading widget
flexibleSpace: SomeWidget(),
)
),
This way you can keep the elevation of AppBar for keeping its shadow visible and have custom height, which is what I was just looking for. You do have to set the spacing in SomeWidget, though.
The easiest way is to use toolbarHeight property in your AppBar
Example :
AppBar(
title: Text('Flutter is great'),
toolbarHeight: 100,
),
You can add flexibleSpace property in your appBar for more flexibility
Output:
For more controls , Use the PreferedSize widget to create your own appBar
Example :
appBar: PreferredSize(
preferredSize: Size(100, 80), //width and height
// The size the AppBar would prefer if there were no other constraints.
child: SafeArea(
child: Container(
height: 100,
color: Colors.red,
child: Center(child: Text('Fluter is great')),
),
),
),
Don't forget to use a SafeArea widget if you don't have a safeArea
Output :
At the time of writing this, I was not aware of PreferredSize. Cinn's answer is better to achieve this.
You can create your own custom widget with a custom height:
import "package:flutter/material.dart";
class Page extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Column(children : <Widget>[new CustomAppBar("Custom App Bar"), new Container()],);
}
}
class CustomAppBar extends StatelessWidget {
final String title;
final double barHeight = 50.0; // change this for different heights
CustomAppBar(this.title);
#override
Widget build(BuildContext context) {
final double statusbarHeight = MediaQuery
.of(context)
.padding
.top;
return new Container(
padding: new EdgeInsets.only(top: statusbarHeight),
height: statusbarHeight + barHeight,
child: new Center(
child: new Text(
title,
style: new TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
),
),
);
}
}
In addition to #Cinn's answer, you can define a class like this
class MyAppBar extends AppBar with PreferredSizeWidget {
#override
get preferredSize => Size.fromHeight(50);
MyAppBar({Key key, Widget title}) : super(
key: key,
title: title,
// maybe other AppBar properties
);
}
or this way
class MyAppBar extends PreferredSize {
MyAppBar({Key key, Widget title}) : super(
key: key,
preferredSize: Size.fromHeight(50),
child: AppBar(
title: title,
// maybe other AppBar properties
),
);
}
and then use it instead of standard one
You can simply use toolbarHeight, as follows:
appBar: AppBar(
toolbarHeight: 70.0, // add this line
centerTitle: true, // add this line
title: Text('your title'),
),
but if you have any actions the code above doesn't work as you want
you can use this code
AppBar(
centerTitle: true,
title: Padding(
padding: const EdgeInsets.all(16.0),
child: Stack(
alignment: Alignment.center,
children: [
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Chats', style: TextStyle(color:Colors.black),),
Icon(Icons.add, color: Colors.black,),
],
),
Align(
alignment: Alignment.centerRight,
child: Icon(Icons.add, color: Colors.black,),
),
],
),
),
)
Cinn's answer is great, but there's one thing wrong with it.
The PreferredSize widget will start immediately at the top of the screen, without accounting for the status bar, so some of its height will be shadowed by the status bar's height. This also accounts for the side notches.
The solution: Wrap the preferredSize's child with a SafeArea
appBar: PreferredSize(
//Here is the preferred height.
preferredSize: Size.fromHeight(50.0),
child: SafeArea(
child: AppBar(
flexibleSpace: ...
),
),
),
If you don't wanna use the flexibleSpace property, then there's no need for all that, because the other properties of the AppBar will account for the status bar automatically.
simply use toolbar height ...
AppBar(
title: Text("NASHIR'S APP"),
toolbarHeight: 100,
),
You can use the toolbarHeight property of Appbar, it does exactly what you want.
class AppBarWidget extends StatelessWidget with PreferredSizeWidget {
final String title;
const AppBarWidget({Key? key, required this.title}) : super(key: key);
#override`enter code here`
Widget build(BuildContext context) {
return AppBar(
title: Text(title),
centerTitle: true,
elevation: 0,
actions: [
Padding(
padding: const EdgeInsets.only(right: 10),
child: IconButton(
icon: const FaIcon(FontAwesomeIcons.language),
onPressed: () {},
),
),
],
);
}
#override
Size get preferredSize => const Size.fromHeight(40);// change
}
You can use PreferredSize, by this use can set multiple children widget inside their
appBar: PreferredSize(
preferredSize: Size(MediaQuery.of(context).size.width, 75),
child: Column(children: [
AppBar(
centerTitle: true,
toolbarHeight: 74,
backgroundColor: Colors.white,
elevation: 0,
title: Column(
children: [
Text(
viewModel.headingText,
style: sfDisplay16500Text,
),
SizedBox(
height: 8.0,
),
Text(
viewModel.url.toString(),
style: sfDisplay10400LightBlackText,
maxLines: 1,
overflow: TextOverflow.ellipsis,
)
],
),
),
]),
),
or just directly use toolbarHeight property for only increase hight of appBar.
appBar: AppBar(
title: Text('AppBar Texr'),
toolbarHeight: 200.0, // double
),
Extend AppBar class and override preferredSize
class AppBarCustom extends AppBar {
#override
Size get preferredSize => Size.fromHeight(100);
}
then use it as you would use AppBar class
class MyHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBarCustom(),
body:
),
);
}
}
This is simplest and easiest way to change appbar height without changing original theme.
class AppBarSectionView extends StatefulWidget implements PreferredSizeWidget {
const AppBarSectionView({Key? key}) : super(key: key);
#override
_AppBarSectionViewState createState() => _AppBarSectionViewState();
#override
Size get preferredSize => const Size.fromHeight(kToolbarHeight + 20);
}
class _AppBarSectionViewState extends State<AppBarSectionView> {
#override
Widget build(BuildContext context) {
return AppBar(
toolbarHeight: widget.preferredSize.height ,
backgroundColor: Colors.red,
leading: const Icon(Icons.arrow_back_ios_rounded),
title: const Text("This Is Title"),
);
}
}
If you are in Visual Code, Ctrl + Click on AppBar function.
Widget demoPage() {
AppBar appBar = AppBar(
title: Text('Demo'),
);
return Scaffold(
appBar: appBar,
body: /*
page body
*/,
);
}
And edit this piece.
app_bar.dart will open and you can find
preferredSize = new Size.fromHeight(kToolbarHeight + (bottom?.preferredSize?.height ?? 0.0)),
Difference of height!