How can I add another button in Scaffold? - flutter

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.

Related

Flutter Navigate back to home Screen after a time when there is no interaction on the second Screen

Flutter beginner needs help.
Is it possible that the app by himself without a press of a button, navigates from a second screen to the home screen after a period of time, if there is no any interaction on the second Screen.
For example in the following code is it possible to make this?
I don't know how to implement this.
Thanks in advance for some help
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Home(),
);
}
}
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Navigate to a new screen on Button click'),
backgroundColor: Colors.teal),
body: Center(
child: FlatButton(
color: Colors.teal,
textColor: Colors.white,
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context)=>Screen2()));
},
child: Text('GO TO SCREEN 2'),
),
),
);
}
}
class Screen2 extends StatefulWidget {
#override
_Screen2State createState() => _Screen2State();
}
class _Screen2State extends State<Screen2> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Navigate to a new screen on Button click'),
backgroundColor: Colors.blueAccent),
body: Center(
child: FlatButton(
color: Colors.blueAccent,
textColor: Colors.white,
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context)=>Home()));
},
child: Text('GO TO HOME'),
),
),
);
}
}
First, I would recommend pop and not push because Flutter navigator works like a stack.
Next, you can set a timer in the initState function:
#override
void initState() {
Timer(Duration(seconds: 3), () {
Navigator.of(context).pop(MaterialPageRoute(builder: (context) => Home()));
});
super.initState();
}
for a better solution, I would set a timer in the initState function and wrap the entire page with GestureDetector, so that each gesture resets the timer.
Use GestureDetector's behavior property and pass HitTestBehavior.opaque to it, which recognizes entire screen and detects the tap when you tap anywhere on the screen. like this:
import 'dart:async';
import 'package:flutter/material.dart';
class Screen2 extends StatefulWidget {
#override
_Screen2State createState() => _Screen2State();
}
class _Screen2State extends State<Screen2> {
Timer? searchOnStoppedTyping;
_onChangeHandler() {
const duration = Duration(milliseconds: 800); // set the duration that you want call pop() after that.
if (searchOnStoppedTyping != null) {
searchOnStoppedTyping?.cancel(); // clear timer
}
searchOnStoppedTyping = new Timer(duration, () => navigateHome());
}
navigateHome() {
Navigator.of(context).pop(MaterialPageRoute(builder: (context) => Home()));
}
#override
void initState() {
_onChangeHandler();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Navigate to a new screen on Button click'), backgroundColor: Colors.blueAccent),
body: GestureDetector(
//Use GestureDetector's behavior property and pass HitTestBehavior.opaque to it, which recognizes entire screen and detects the tap when you tap anywhere on the screen.
behavior: HitTestBehavior.opaque,
onTap: _onChangeHandler,
child: yourBody...,
),
);
}
}
class Screen2 extends StatefulWidget {
#override
_Screen2State createState() => _Screen2State();
}
class _Screen2State extends State<Screen2> {
// try to add init state and add timer inside it then it will navigate after duration
void initState() {
super.initState();
Timer(Duration(seconds: 4), (){
Navigator.of(context).pop(MaterialPageRoute(builder: (context)=>Home()));
});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Navigate to a new screen on Button click'),
backgroundColor: Colors.blueAccent),
body: Center(
child: FlatButton(
color: Colors.blueAccent,
textColor: Colors.white,
onPressed: () {
// i moved this line inside the Timer , look at initState
},
child: Text('GO TO HOME'),
),
),
);
}
}

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"),
)
]),
),
),
);
}
}

Hiding/Removing StatusBar in Flutter (on button click)

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;
}
}
}

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: