Hiding/Removing StatusBar in Flutter (on button click) - flutter

In my app when button clicked, I want statusBar to be absolutely hidden.
I've already tried SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]); and SystemChrome.setEnabledSystemUIOverlays([]);
it makes statusBar black but it still takes space on top of the screen.
So how can I make statusBar disappear fully when I click specific button?

In Flutter 2.5, you would do this using the following snippet:
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
You can use any of the following SystemUiMode enums:
immersive
immersiveSticky
edgeToEdge
leanBack

SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]); works fine, the remaining space you are seeing is just the AppBar. You can change the size of the AppBar at the same time you hide the status bar, by wrapping it in a PreferredSize widget and setting the size property to a variable that you change with setState when the button is pressed.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
double appBarHeight = 55;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(appBarHeight),
child: AppBar(
title: const Text('Hide Status Bar'),
),
),
body: Scaffold(
body: Center(
child: RaisedButton(
onPressed: () {
SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]);
setState(() {
appBarHeight = 35; // After status bar hidden, make AppBar height smaller
});
},
child: Text("Hide Bar"),
),
),
),
),
);
}
}
EDIT: TO HIDE STATUS BAR, NAV BAR, AND THEIR RESERVED SPACES
To hide both status bar, navigation bar, and the spaces that are reserved for them like this:
You can get rid of both using SystemChrome.setEnabledSystemUIOverlays([]);, then set your AppBar to null using a bool and setState, and set the resizeToAvoidBottomInset property of your scaffold to false.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool showAppBar = true;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
resizeToAvoidBottomInset: false,
appBar: appBar(),
body: Center(
child: RaisedButton(
onPressed: () {
SystemChrome.setEnabledSystemUIOverlays([]);
setState(() {
showAppBar = false;
});
},
child: Text("Hide Bar"),
),
),
),
);
}
appBar() {
if (showAppBar) {
return AppBar(
title: const Text('Hide Status Bar'),
);
} else {
return null;
}
}
}

Related

Hi I'm new to dart and flutter I do not know why this isnt working, nothing happens when the button is pressed and I have no clue why

New to this so I have no clue whats wrong here. I need the code to add 1 to _count when the button is pressed but nothing happens when the button is pressed
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
int _count = 0;
void main() {
var app = MaterialApp(
home: Scaffold(
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
_count++;
return _count.toString();
},
),
appBar: AppBar(title: Text('Welcome')),
body: Center(
child: Text('You have pressed the button $_count times.'),
),
),
);
runApp(app);
}
To update state you need StatefulWiget to have a state with your count data, then call setState when you change your data:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int _count = 0;
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Material App',
home: Scaffold(
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
setState((){_count++;});
},
),
appBar: AppBar(title: Text('Welcome')),
body: Center(
child: Text('You have pressed the button $_count times.'),
),
),
);
}
}
You can fast check result copying this code to dartpad and pressing run.
It will be good start for you if you check this page, knowing what is state in flutter.

How to redraw widget on Flutter when a value changes?

Suppose the following simple StatefulWidget example:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
int value = 0;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('App Example')),
body: Row(children:[
Text("hello"),
RaisedButton(
textColor: Colors.white,
color: Colors.blue,
onPressed: (){setState(() { value+=1; });},
child: new Text("Add"),
)
]),
),
);
}
}
My main problem is: how do I redraw Text("hello") every time value changes? I'm using Text as an example, but it could be an widget that has an internal state, and I'd like to redraw it when the value changes. It does not necessarily depends on the value but I want to redraw anyways when value changes.
I don't have much idea ab8 it. I do this kind of stuff by wrapping it into an container and setting height and width equal to some variable.
If your question is if you just want to change the state of that specific widget(Example the Text widget) without disturbing the other widgets. This are some of the state management's which might help other than SetState (My personal fav. BLOC and REDUx).
Update this line:-
Text("hello ${value}"),
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
int value = 0;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('App Example')),
body: Center(
child: Column(children: [
Text("hello ${value}"),
RaisedButton(
textColor: Colors.white,
color: Colors.blue,
onPressed: () {
setState(() {
value += 1;
});
},
child: new Text("Add"),
)
]),
),
),
);
}
}

How can I add another button in Scaffold?

I am new to flutter and Im trying to rebuild the demo app. How can I add the FloatingActioButton to the App it seems that I can't add another body or something. How can I do this ?
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
int _counter = 0;
void increase_Counter() {
setState(() {
_counter += 1;
});
}
Widget build(BuildContext context) {
return MaterialApp(home: Scaffold(
appBar: AppBar(
title: Text("Demo App"),
),
body: Center(
child: Text("Your press button $_counter times"),)
body:(FloatingActionButton(onPressed: increase_Counter,)
),)
,
);
}
}
You can check the below code. Floating action button always goes inside scaffold.
Widget build(BuildContext context) {
return MaterialApp(home: Scaffold(
appBar: AppBar(
title: Text("Demo App"),
),
body: Center(
child: Text("Your press button $_counter times"),),
floatingActionButton: FloatingActionButton(
onPressed: () {
// Add your onPressed code here!
},
child: Icon(Icons.navigation),
backgroundColor: Colors.green,
),
);
}
And you can also follow FloatingActionButton to get better understanding.

How to fix appbar while navigating through pages in flutter?

I want to navigate through screens but I need to change only the content of the body and the appbar stays as it is. I am having 4 files namely main.dart, screen1.dart, screen2.dart, and globals.dart. Screen1 is having a button to goto Screen2 and vice versa. When I clicked the button in screen1 it need to navigate to screen 2 and vice versa, but when I clicked the button nothing is happening. Here is my code:
main.dart
import 'package:demo/globals.dart';
import 'package:demo/screen2.dart';
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp(),
),
);
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
void initState() {
buildBody = Screen1();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.deepOrange,
title: Text('Fixed AppBar'),
centerTitle: true,
),
body: buildBody,
);
}
}
screen1.dart
import 'package:demo/screen2.dart';
import 'package:flutter/material.dart';
class Screen1 extends StatefulWidget {
#override
_Screen1State createState() => _Screen1State();
}
class _Screen1State extends State<Screen1> {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.green,
child: Center(
child: FlatButton(
child: Text('Goto Screen 2', style: TextStyle(color: Colors.white)),
onPressed: () {
setState(() {
buildBody = Screen2();
});
},
),
),
);
}
}
screen2.dart
import 'package:demo/screen1.dart';
import 'package:flutter/material.dart';
class Screen2 extends StatefulWidget {
#override
_Screen2State createState() => _Screen2State();
}
class _Screen2State extends State<Screen2> {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.brown,
child: Center(
child: FlatButton(
child: Text(
'Goto Screen 1',
style: TextStyle(color: Colors.white),
),
onPressed: () {
setState(() {
buildBody = Screen1();
});
},
),
),
);
}
}
globals.dart
import 'package:flutter/material.dart';
Widget buildBody;
Instead of using Scaffold in main file after MaterialApp
, use it in every separated screen use you custom content and the title you want.
Check out PageView https://api.flutter.dev/flutter/widgets/PageView-class.html
From flutter docs. I think that will work or use Tabs

Navigating to another page from drawer menu and setting title to app bar

i am new to flutter and would like someone to help me with code i found in github that i would like to use. take a look at the link below
https://github.com/JohannesMilke/drawer_example
this is an example of a navigational drawer. i like the way the developer coded it and would like to use this example. the problem is that the developer didnt implement navigating to another page. when you click on item in the drawer, it just print a message in the console.
i want to take this a step further. i want to modified the code so that when you click on a item it will navigate to another page and the drawer will b closed. the drawer icon should remain on the toolbar on the new page displayed. also, when you navigate to another page the title of that page should be set in the toolbar.
when i looked at the code , i have an idea where to change but i am not successful. i think i need to change the body tag at the bottom of the code. the problem is that i dont know how to call the DrawerWidgetState class in drawer_widget.dart file.
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final String appTitle = 'Ttitle';
#override
Widget build(BuildContext context) => MaterialApp(
title: appTitle,
theme: ThemeData(
primaryColor: Colors.red,
textTheme: TextTheme(
subhead: TextStyle(
color: Colors.black.withOpacity(0.4),
),
),
dividerColor: Colors.black.withOpacity(0.4),
),
home: MainPage(appTitle: appTitle),
);
}
class MainPage extends StatefulWidget {
final String appTitle;
const MainPage({this.appTitle});
#override
MainPageState createState() => MainPageState();
}
class MainPageState extends State<MainPage> {
#override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: Text(widget.appTitle),
),
drawer: DrawerWidget(),
body: container()
);
}
i define the following function in drawer_widget.dart file
getDrawerItemWidget(int pos) {
print('testing');
switch (pos) {
case 0:
return new FirstFragment();
case 1:
return new SecondFragment();
case 2:
return new ThirdFragment();
default:
return new Text("Error");
}
}
but i dont know how to call it from Mainpage Body tag and set title accordingly. can someone help modify the code so that i can nagivate to another page and set title? full code is in
https://github.com/JohannesMilke/drawer_example
thanks in advance
Using the drawer_example library you need to make some small changes in order to make it work.
Over your drawer_widget.dart add this add the beginning:
typedef TitleCallback = void Function(String, int);
Once you do that, your Drawer StatefulWidget should looks this way:
class DrawerWidget extends StatefulWidget {
final TitleCallback callback;
final int tabIndex;
#override
DrawerWidgetState createState() => DrawerWidgetState();
DrawerWidget(this.callback, this.tabIndex);
}
and your initState:
#override
void initState() {
selectedDrawerIndex = widget.tabIndex;
selectedProfileIndex = 0;
super.initState();
}
This will be the constructor to pass the new value back to your main.dart file.
Inside the ListTile, you can add the following logic:
ListTile(
leading: Icon(item.icon),
title: Text(item.name),
selected: selectedDrawerIndex == currentIndex,
onTap: () {
final item = getOffsetIndex(drawerGroups, currentIndex);
print('Selected index $selectedDrawerIndex with name ${item.name}');
setState(() {
selectedDrawerIndex = currentIndex;
widget.callback(item.name, selectedDrawerIndex);
});
Navigator.pop(context); // to close the Drawer
},
)
If you can check, the line: widget.callback(item.name); sends the tab name over the callback and that logic can be applied any where you want to change your title. It can even be a hard coded title like:
widget.callback("Second Tab");
Now, going back to your main.dart file:
class MyApp extends StatefulWidget {
final String title;
ListExample(this.title);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<Widget> _fragments = <Widget> [
Container(
child: Text("Fragment One"),
),
Container(
child: Text("Fragment Two"),
),
Container(
child: Text("Fragment Three"),
),
];
String titleAppBar = "Testing";
int tabIndex = 0;
#override
void initState() {
setState(() {
titleAppBar = widget.title;
});
super.initState();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: widget.title,
home: Scaffold(
appBar: AppBar(
title: Text(titleAppBar),
),
drawer: DrawerWidget((title, index) {
setState(() {
titleAppBar = title;
tabIndex = index;
});
}, tabIndex),
body: _fragments[tabIndex],
),
);
}
}
Final Result:
Looking at the example on GitHub, it's overcomplicating something that's too easy with Flutter.
Here's a simple example on how to use a Drawer on Flutter:
main.dart
import 'package:flutter/material.dart';
import 'another_page.dart';
import 'home_page.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
// declaring your routes will allow you to push and remove everything from the stack (including the drawer) with pushNamedAndRemoveUntil()
routes: {
'home': (context) => HomePage(),
'anotherPage': (context) => AnotherPage(),
},
initialRoute: 'home',
);
}
}
home_page.dart (another_page.dart is exactly the same for illustration purpose)
import 'package:flutter/material.dart';
import 'menu_drawer.dart';
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: MenuDrawer(),
appBar: AppBar(
title: Text('Home'),
),
body: Center(
child: Text('Home'),
),
);
}
}
menu_drawer.dart
import 'package:flutter/material.dart';
class MenuDrawer extends StatelessWidget {
// Push the page and remove everything else
navigateToPage(BuildContext context, String page) {
Navigator.of(context).pushNamedAndRemoveUntil(page, (Route<dynamic> route) => false);
}
#override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
// This could be mapped from a List of items
children: <Widget>[
ListTile(
leading: Icon(Icons.home),
title: Text('Home'),
onTap: () => navigateToPage(context, 'home'),
),
ListTile(
leading: Icon(Icons.panorama),
title: Text('Another page'),
onTap: () => navigateToPage(context, 'anotherPage'),
),
],
),
);
}
}
Final result: