How do I implement a Drawer menu in my pages? - flutter

I have a dart file as a 'MyDrawer' and I want to add this drawer menu to my dashboard page. Here is my code. I don't know why it doesn't work.
import 'package:flutter/material.dart';
class MyDrawer extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Menu drawer'),
decoration: BoxDecoration(
color: Colors.red,
),
),
ListTile(
leading: Icon(Icons.home, size: 40,),
title: Text('First item'),
subtitle: Text("This is the 1st item"),
trailing: Icon(Icons.more_vert),
onTap: () {
},
),
ListTile(
title: Text('Second item'),
onTap: () {
},
),
],
),
);}}
And I'm calling this drawer menu in my dashboard page. It's like that;
class Dash extends StatefulWidget { ...
class _DashState extends State<Dash> { ...
#override
void initState(){ ...
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: MyDrawer(),
body: Container(
... ),

Your drawer MyDrawer should be a StatelessWidget that returns a Drawer.
This is how you should do it:
class DashboardPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: MyDrawer(),
);
}
}
class MyDrawer extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
// Important: Remove any padding from the ListView.
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Menu drawer'),
decoration: BoxDecoration(
color: Colors.red,
),
),
ListTile(
leading: Icon(Icons.home, size: 40,),
title: Text('First item'),
subtitle: Text("This is the 1st item"),
trailing: Icon(Icons.more_vert),
onTap: () {
},
),
ListTile(
title: Text('Second item'),
onTap: () {
},
),
],
),
);
}
}

All I needed was to add an appbar. I definitely missed these details. Here is the updated version.
class Dash extends StatefulWidget { ...
class _DashState extends State<Dash> { ...
#override
void initState(){ ...
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
drawer: MyDrawer(),
body: Container(
... ),

Related

Circular button - flutter

I am trying to create a circular button, but there is an error when I try to use ElevatedButton:
This is the code:
import 'package:flutter/material.dart';
void main() => runApp(Menu());
class Menu extends StatefulWidget {
const Menu({super.key});
#override
State<Menu> createState() => _MenuState();
}
class _MenuState extends State<Menu> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
),
body: Center(
child: Container(
ElevatedButton(
backgroundColor: Colors.amberAccent,
onPressed: () {},
child: Icon(
Icons.train,
size: 35,
color: Colors.black,
),
),
),
)
);
}
}
I have also tried to create a FloatingActionButton, but it didn't worked.
Container provide child and you need to use style for decoration.
class _MenuState extends State<Menu> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Container(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.amberAccent,
),
onPressed: () {},
child: Icon(
Icons.train,
size: 35,
color: Colors.black,
),
),
),
));
}
}

How to have a drawer with 2 separate colors in Flutter

I'm trying to figure out how to have the green fill up the entire drawer space under the yellow header. Right now I have my ListTiles wrapped in a Column, in a Container, with the Container color set to green. All help is appreciated.
What I have so far
One of the ways could be wrapping the ListView that you are probably using with a Container that has color green. Please see the code below :
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(home: HomePage());
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Flutter Demo"),
),
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
color: Colors.white,
),
drawer: Container(
color: Colors.green,
child: ListView(
children: <Widget>[
DrawerHeader(
padding: const EdgeInsets.all(0),
child: Container(
child: const Center(child: Text("Profile")),
color: Colors.yellow,
),
),
ListTile(
title: const Text('Item 1'),
tileColor: Colors.green,
onTap: () {
Navigator.pop(context);
},
),
ListTile(
title: const Text('Item 2'),
tileColor: Colors.green,
onTap: () {
Navigator.pop(context);
},
),
],
),
),
);
}
}

Flutter: How to implement floating SearchBar (Custom AppBar) with Drawer like Google Apps

Can somebody please tell me how can I integrate the menu drawer inside the Row widget instead of in a Scaffold widget? Something like Gmail's app (search with drawer icon).
It's very simple.
Screenshot of the output
Steps:
Step 1:
Define the scaffold with a custom Appbar widget
return Scaffold(
appBar: FloatAppBar(),
body: Center(
child: Text('Body'),
),
drawer: Drawer(
child: SafeArea(
right: false,
child: Center(
child: Text('Drawer content'),
),
),
),
);
Step 2:
Implement the PreferredSizeWidget to create a custom AppBar
class FloatAppBar extends StatelessWidget with PreferredSizeWidget {
step 3:
Use Scaffold.of(context).openDrawer(); to open the drawer when required.
Here is the complete snippet.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Playground',
home: TestPage(),
);
}
}
class TestPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: FloatAppBar(),
body: Center(
child: Text('Body'),
),
drawer: Drawer(
child: SafeArea(
right: false,
child: Center(
child: Text('Drawer content'),
),
),
),
);
}
}
class FloatAppBar extends StatelessWidget with PreferredSizeWidget {
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Positioned(
top: 10,
right: 15,
left: 15,
child: Container(
color: Colors.white,
child: Row(
children: <Widget>[
Material(
type: MaterialType.transparency,
child: IconButton(
splashColor: Colors.grey,
icon: Icon(Icons.menu),
onPressed: () {
Scaffold.of(context).openDrawer();
},
),
),
Expanded(
child: TextField(
cursorColor: Colors.black,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.go,
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(horizontal: 15),
hintText: "Search..."),
),
),
],
),
),
),
],
);
}
#override
Size get preferredSize => Size.fromHeight(kToolbarHeight);
}
See the live demo here.
the AppBar widget alredy has mechanisms for that,
AppBar(
drawaer: YourDrawer(),
actions: [
IconButton(
icon: Icon(Icons.search),
onPressed: (){}
)
]
);
it will create the Gmail appbar you want

Reorderable List glitches keyboard when not on home screen

I am working on a project with textfields that are members of a reorderable list. My problem is when the list is accessed from a Navigator push to a new screen the text fields within the ReorderableListView on the new screen glitches causing the keyboard to pop up then quickly disappear. The code is identical for both lists, does anyone know what may be causing this bug? I created a sample main.dart to demonstrate the effect:
import 'package:flutter/material.dart';
void main() => runApp(App());
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Reorderable List bug',
home: MainPage(),
);
}
}
class MainPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Main Page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: ReorderableListView(
onReorder: (old_index, new_index) {},
children: <Widget>[
textCard(),
textCard2()
],
),
),
Text('Keyboard behaves as expected here but will glitch on following page'),
RaisedButton(
textColor: Colors.white,
color: Colors.blue,
child: Text('Go to SubPage'),
onPressed: () {
navigateToSubPage(context);
},
)
],
),
),
);
}
Future navigateToSubPage(context) async {
Navigator.push(context, MaterialPageRoute(builder: (context) => SubPage()));
}
}
class SubPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: ReorderableListView(
onReorder: (old_index, new_index) {},
children: <Widget>[
textCard(),
textCard2(),
RaisedButton(
key: ValueKey('3'),
textColor: Colors.white,
color: Colors.redAccent,
child: Text('Back to Main Page'),
onPressed: () {
Navigator.pop(context);
},
)
],
),
);
}
}
Widget textCard() {
return Card(
key: ValueKey('1'),
child: Padding(
padding: EdgeInsets.all(15.0),
child: Row(
children: <Widget>[
Padding(
padding: EdgeInsets.only(right: 15.0),
child: Text(
'1.',
)),
Expanded(
child: TextFormField(
decoration: InputDecoration(labelText: 'Enter text'),
)
)
],
)));
}
Widget textCard2() {
return Card(
key: ValueKey('2'),
child: TextFormField(
decoration: InputDecoration(
labelText: 'Enter text'
),
),
);
}

How to keep AppBar and back arrow stationary when navigating to a new screen

I want to have the top half of by screen appear static when navigating between pages in Flutter.
To try to make this happen I put use the Hero widget and use it on a column that contains an AppBar and some other content that I want to appear static when pushing a new page.
The App Bar itself remains static but the back arrow disappears when the animation starts and reappears when the animation is done.
How can I have the back arrow remain visible the entire time while the rest of the page is animating into place?
class FirstScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Hero(
tag: 'top',
child: Column(
children: <Widget>[
AppBar(
title: Text('First'),
backgroundColor: Color.fromARGB(255, 50, 64, 182),
),
Container(
height: 80.0,
)
],
),
),
RaisedButton(
child: Text('Next'),
onPressed: () {
Navigator.pushNamed(context, '/second');
},
),
],
),
);
}
}
class SecondScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Hero(
tag: 'top',
child: Column(
children: <Widget>[
AppBar(
title: Text('Second'),
),
Container(
height: 80.0,
// color: Colors.green,
),
],
),
),
RaisedButton(
child: Text('Back'),
onPressed: () {
Navigator.pop(context);
},
),
],
),
);
}
}
Things weren't quite set up right in your code. It should go Scaffold/Hero/your content. I've also used this simple fading page route when performing the navigation:
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First'),
leading: Icon(null),
backgroundColor: Color.fromARGB(255, 50, 64, 182)),
body: Hero(
tag: 'top',
child: Column(
children: <Widget>[
Container(height: 80.0),
RaisedButton(
child: Text('Next'),
onPressed: () {
Navigator.push(context, MyCustomRoute(builder: (context) {
return SecondScreen();
}));
},
),
],
),
),
);
}
}
class SecondScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second'),
leading: IconButton(icon: Icon(Icons.arrow_back), onPressed: () {
Navigator.pop(context);
},),
backgroundColor: Color.fromARGB(255, 50, 64, 182)),
body: Hero(
tag: 'top',
child: Column(
children: <Widget>[
Container(height: 80.0),
RaisedButton(
child: Text('Back'),
onPressed: () {
Navigator.pop(context);
},
),
],
),
),
);
}
}
class MyCustomRoute<T> extends MaterialPageRoute<T> {
MyCustomRoute({ WidgetBuilder builder, RouteSettings settings })
: super(builder: builder, settings: settings);
#override
Widget buildTransitions(BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child) {
if (settings.isInitialRoute)
return child;
// Fades between routes. (If you don't want any animation,
// just return child.)
return new FadeTransition(opacity: animation, child: child);
}
}
You could do automaticallyImplyLeading: false and then do
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () => Navigator.of(context).pop(),
),
I have it done this way, by adding automaticallyImplyLeading: true,
Hope this solves your problem!
appBar: AppBar(
automaticallyImplyLeading: true,
),