Making Icon center of FlattButton issue after upgrading flutter - flutter

How to make this arrow icon in the center of the button
it's see the edge of icon is the center of icon, and I want make flutter see the center of icon is the center of icon
for more explain:
my code:
AppBar(
backgroundColor: Colors.transparent,
leading:
// Here the code of the button
SizedBox(
height: getProportionateScreenHeight(20),
width: getProportionateScreenWidth(10),
child: Padding(
padding: EdgeInsets.all(8),
child: FlatButton(
padding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
color: Colors.white,
onPressed: () {
Navigator.pop(context);
},
child: Center(
child: Icon(
Icons.arrow_back_ios,
),
),
),
),
),
// ....
actions: [
IconButton(
icon: Icon(
Icons.favorite,
color: favFlag ? Colors.red : Colors.red[100],
),
onPressed: () {
setState(() {
favFlag = !favFlag;
});
},
),
],
);
And it's was working with me before last upgrade.

I think there is some problem with the use of your height and width factor for SizedBox. I used simple values for these and it is working fine.
In fact, I removed the SizedBox widget and there was no such effect. I have attached the pic after the code as well :)
appBar: AppBar(
backgroundColor: Colors.transparent,
leading:
// Here the code of the button
SizedBox(
height: 20,
width: 20,
child: Padding(
padding: EdgeInsets.all(8),
child: FlatButton(
padding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
color: Colors.white,
onPressed: () {
// Navigator.pop(context);
},
child: Center(
child: Icon(
Icons.arrow_back_ios,
),
),
),
),
),
actions: [
IconButton(
icon: Icon(
Icons.favorite,
color: favFlag ? Colors.red : Colors.red[100],
),
onPressed: () {
setState(() {
favFlag = !favFlag;
});
},
),
],
),
Output:

My solution
AppBar(
backgroundColor: Colors.transparent,
// Here the code of the button
leading: Padding(
padding: EdgeInsets.all(8),
child: FlatButton(
padding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
color: Colors.white,
onPressed: () {
Navigator.pop(context);
},
child: Stack(
alignment: Alignment.center,
children: [
Positioned.directional(
textDirection: Directionality.of(context),
end: 3,
child: Icon(
Icons.arrow_back_ios,
),
),
],
),
),
),
// ....
actions: [
IconButton(
icon: Icon(
Icons.favorite,
color: favFlag ? Colors.red : Colors.red[100],
),
onPressed: () {
setState(() {
favFlag = !favFlag;
});
AdsService.listByPagination();
},
),
],
);
I've positioned it to center manually, so I prefer if there an another clean short solution.

Related

flutter create a button with 2 icons

[
I can create a button with an icon using this code
ElevatedButton.icon(
icon: Icon(
Icons.home,
color: Colors.green,
size: 30.0,
),
label: Text('Elevated Button'),
onPressed: () {
print('Button Pressed');
},
style: ElevatedButton.styleFrom(
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(20.0),
),
),
)
but how to put an arrow on the right side of the button?
As per your shared Image I have try same design in Various ways choice is yours 😊which way you want to try.
Using ElevatedButton.icon
ElevatedButton.icon(
icon: const Icon(
Icons.mail,
color: Colors.green,
size: 30.0,
),
label: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Text('Change Email Address'),
Icon(Icons.arrow_forward_ios)
],
),
onPressed: () {
print('Button Pressed');
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
foregroundColor: Colors.black,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
side: const BorderSide(color: Colors.black),
),
fixedSize: const Size(double.infinity, 40),
),
),
Result Using ElevatedButton.icon ->
Using OutlinedButton.icon
OutlinedButton.icon(
icon: const Icon(
Icons.mail,
color: Colors.green,
size: 30.0,
),
label: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Text(
'Change Email Address',
style: TextStyle(
color: Colors.black,
),
),
Icon(
Icons.arrow_forward_ios,
color: Colors.grey,
)
],
),
onPressed: () {
print('Button Pressed');
},
style: ElevatedButton.styleFrom(
side: const BorderSide(color: Colors.black,),
fixedSize: const Size(double.infinity, 40),
),
),
Result Using OutlinedButton.icon ->
Using ListTile
ListTile(
onTap: () {
print('Button Pressed');
},
visualDensity: const VisualDensity(horizontal: -4,vertical: -4),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
side: const BorderSide(color: Colors.black),
),
leading: const Icon(Icons.mail,color: Colors.green),
trailing: const Icon(Icons.arrow_forward_ios),
title: const Text('Change Email Address'),
),
Result Using ListTile ->
Using GestureDetector
GestureDetector(
onTap: () {
print('Button Pressed');
},
child: Container(
padding:const EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
width: 1,
),
borderRadius: BorderRadius.circular(10),),
child: Row(
children: const [
Icon(Icons.mail, color: Colors.green),
SizedBox(width: 10,),
Text('Change Email Address'),
Spacer(),
Icon(Icons.arrow_forward_ios),
],
),
),
),
Result Using GestureDetector ->
Using InkWell
InkWell(
onTap: () {
print('Button Pressed');
},
child: Container(
padding:const EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
width: 1,
),
borderRadius: BorderRadius.circular(10),),
child: Row(
children: const [
Icon(Icons.mail, color: Colors.green),
SizedBox(width: 10,),
Text('Change Email Address'),
Spacer(),
Icon(Icons.arrow_forward_ios),
],
),
),
),
Result Using InkWell->
It seems like you want a ListTile widget, as it has leading/trailing properties:
Container(
margin: const EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
width: 1,
),
),
child: const ListTile(
leading: Icon(Icons.mail),
trailing: Icon(Icons.arrow_forward_ios),
title: Text('Change Email Address'),
),
)
You can also use IconButton instead of a regular Icon in this example.
To add two icons to an elevated button, just wrap your child widget with a row widget. See implementation below:
ElevatedButton(
onPressed: () {},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Icon(Icons.home),
Text('Home'),
Icon(Icons.navigate_next)
],
),
),

How do I add my app 3 rounded border buttons?

I need to add 3 buttons at the bottom, all buttons need in one row top of the body content
I need to add 3 buttons at the bottom of app
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('WinLife'),
elevation: 10,
backgroundColor: const Color(0XFF82B58D),
leading: Container(
padding: EdgeInsets.all(5),
child: Image.asset('assets/images/logo/WinLife.png'),
),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.favorite,
color: Colors.white,
),
onPressed: () {},
),
IconButton(
icon: Icon(
Icons.settings,
color: Colors.white,
),
onPressed: () {},
)
],
),
body: ListView.builder(
itemBuilder: (BuildContext ctx, int index) {
return Padding(
padding: EdgeInsets.all(10),
child: Card(
shadowColor: const Color(0XFF82B58D),
shape: Border.all(
color: const Color(0XFF82B58D),
width: 2,
),
elevation: 50,
color: const Color(0XFF82B58D),
child: Column(
children: <Widget>[
Image.asset(imgList[index]),
SizedBox(
height: 200,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: const <Widget>[
Icon(
Icons.favorite,
color: Colors.white,
size: 25,
),
Icon(
Icons.download,
color: Colors.white,
size: 25,
),
Icon(
Icons.share,
color: Colors.white,
size: 25,
),
],
),
],
),
),
);
},
itemCount: imgList.length,
),
);
}
There is a property called persistentFooterButtons in scaffold widget. It is using to show widgets to the screen footer. you can add any type of widgets inside to that. below some example code with output image FYR
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('WinLife'),
elevation: 10,
backgroundColor: const Color(0XFF82B58D),
leading: Container(
padding: const EdgeInsets.all(5),
child: Image.asset('assets/images/logo/WinLife.png'),
),
actions: <Widget>[
IconButton(
icon: const Icon(
Icons.favorite,
color: Colors.white,
),
onPressed: () {},
),
IconButton(
icon: const Icon(
Icons.settings,
color: Colors.white,
),
onPressed: () {},
)
],
),
body: Container(),
persistentFooterButtons: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
persistentFooterButtonWidget(),
persistentFooterButtonWidget(),
persistentFooterButtonWidget(),
],
),
],
);
}
persistentFooterButtonWidget() {
return OutlinedButton.icon(
label: const Text("Book now", style: TextStyle(color: Colors.black)),
onPressed: () {},
icon: const Icon(Icons.library_add_check_sharp, color: Colors.black, size: 20.0),
style: ButtonStyle(
fixedSize: MaterialStateProperty.all(
const Size(170.0, 40.0),
),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
)),
side: MaterialStateProperty.all(
BorderSide(color: Colors.orange.shade200, width: 2)),
overlayColor: MaterialStateProperty.resolveWith<Color?>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.hovered)) {
return Colors.orange.shade200;
}
if (states.contains(MaterialState.pressed)) {
return Colors.orange.shade200;
}
return null; // Defer to the widget's default.
}),
),
);
}

Flutter: strange bug in row with aligment spaceEvenly

In my app, I often use conditional widget visibility to hide or display a widget. It works fine but recently, the design was not as expected as you can see in below images.
All Chips are laid in a Row with mainAxisAlignment: MainAxisAlignment.spaceEvenly. When there are 5 buttons, the design is ok, but with 4 buttons (the middle one is hidden), a additional space appears in the middle, which is not perfect.
Here the code
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ActionChip(
backgroundColor: Theme.of(context).colorScheme.onSecondary,
padding: EdgeInsets.all(4),
shape: const CircleBorder(),
label: const Icon(
Icons.school,
),
onPressed: () {...
},
),
ActionChip(
backgroundColor: Theme.of(context).colorScheme.onSecondary,
padding: EdgeInsets.all(4),
shape: const CircleBorder(),
label: const ImageIcon(
AssetImage("assets/images/Intervention.png"),
),
onPressed: () {
...
},
),
deviceId != -1
? ActionChip(
backgroundColor:
Theme.of(context).colorScheme.onSecondary,
padding: EdgeInsets.all(4),
shape: const CircleBorder(),
label: const ImageIcon(
AssetImage("assets/images/History.png"),
),
onPressed: () {
...
},
)
: const SizedBox(
),
ActionChip(
backgroundColor: Theme.of(context).colorScheme.onSecondary,
padding: EdgeInsets.all(4),
shape: const CircleBorder(),
label: const Icon(
Icons.save_alt,
),
onPressed: () {
...
},
),
ActionChip(
backgroundColor: Theme.of(context).colorScheme.onSecondary,
padding: EdgeInsets.all(4),
shape: const CircleBorder(),
label: const Icon(
Icons.settings,
),
onPressed: () {
...
},
),
],
),
I tried to put the middle button in a Visibility widget, but the result was the same.
How to solve this ugly problem?
Thank you
When you use SizedBox it actually take invisible space in that row so row consider it as an item and put padding around it because of spaceEvenly setting. Instead of put SizedBox in else condition, you can use if and set nothing for else condition, like this:
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ActionChip(
backgroundColor: Theme.of(context).colorScheme.onSecondary,
padding: EdgeInsets.all(4),
shape: const CircleBorder(),
label: const Icon(
Icons.school,
),
onPressed: () {...
},
),
ActionChip(
backgroundColor: Theme.of(context).colorScheme.onSecondary,
padding: EdgeInsets.all(4),
shape: const CircleBorder(),
label: const ImageIcon(
AssetImage("assets/images/Intervention.png"),
),
onPressed: () {
...
},
),
if(deviceId != -1) //<--- add this
ActionChip(
backgroundColor:
Theme.of(context).colorScheme.onSecondary,
padding: EdgeInsets.all(4),
shape: const CircleBorder(),
label: const ImageIcon(
AssetImage("assets/images/History.png"),
),
onPressed: () {
...
},
),
ActionChip(
backgroundColor: Theme.of(context).colorScheme.onSecondary,
padding: EdgeInsets.all(4),
shape: const CircleBorder(),
label: const Icon(
Icons.save_alt,
),
onPressed: () {
...
},
),
ActionChip(
backgroundColor: Theme.of(context).colorScheme.onSecondary,
padding: EdgeInsets.all(4),
shape: const CircleBorder(),
label: const Icon(
Icons.settings,
),
onPressed: () {
...
},
),
],
),
Result: top row is for using if the second row is for not using it:

How to open drawer with iconbutton in Flutter?

Well, I was trying to create my custom appbar but I keep editing my column widget with properties I wanted in my appbar and it worked same as I wanted the appbar(as you can see in image) so I thought I dont need a appbar now. But now I want to implement a drawer which can be access by my iconbutton (which is implemented in top left corner of my widget). Actually drawer is implemented bcoz i can use it with sliding action, but I think its hidden behind my widget! I searched on internet and found some codes but since I dont have deep knowledge of any other programming knowledge so its little hard to understand the syntax for me. How can I access this drawer with my IconButton???
enter image description here
This is my page source code. NOTE: sorry i could not update the upper part of my bcoz i dont know how to format it in stackoverflow so its getting input as text instead of code snippet so I am avoiding it
return Scaffold(
backgroundColor: Colors.white,
drawer: CstmDrawer(),
body: SafeArea(
child: Column(
children: [
Row(
children: [
Container(
height: 150.0,
width: MediaQuery.of(context).size.width * 1.0,
child: Stack(
children: [
Container(
height: 130.0,
width: MediaQuery.of(context).size.width * 1.0,
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.vertical(
bottom: Radius.elliptical(
MediaQuery.of(context).size.width, 100.0),
),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
onPressed: () {
Scaffold.of(context).openDrawer(); //I found this code on internet but it gives error "Scaffold.of() called with a context that does not contain a Scaffold."
},
icon: Icon(Icons.menu),
),
Container(
child: Row(
children: [
IconButton(
onPressed: () {},
icon: Icon(
Icons.notifications_active_outlined)),
IconButton(
onPressed: () {},
icon: Icon(Icons.shopping_cart_outlined)),
],
),
),
],
),
),
Positioned(
bottom: 20.0,
right: MediaQuery.of(context).size.width * 0.07,
child: Container(
height: 40.0,
width: MediaQuery.of(context).size.width * 0.85,
child: Theme(
data: ThemeData(primaryColor: Colors.black),
child: TextField(
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
prefixIcon: Icon(Icons.search),
hintText: "Search Here",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
),
),
),
),
),
],
),
),
],
),
],
),
),
);
Drawer source code.
return Drawer(
elevation: 16.0,
child: Column(
children: [
UserAccountsDrawerHeader(
onDetailsPressed: (){},
currentAccountPicture: CircleAvatar(
backgroundColor: Colors.white,
child: IconButton(
onPressed: (){},
tooltip: "Add Photo",
splashColor: Colors.black,
icon: Icon(
Icons.add_a_photo_rounded,
),
),
),
accountName: Text(
"My Name"
),
accountEmail: Text(
"myemail#gmail.com",
),
),
ListTile(
//tileColor: Colors.green,
onTap: (){},
leading: Icon(Icons.person),
hoverColor: Colors.grey,
title: Text("My Account"),
),
Divider(),
ListTile(
onTap: (){},
leading: Icon(Icons.shopping_cart_outlined),
hoverColor: Colors.grey,
title: Text("Cart"),
),
Divider(),
ListTile(
onTap: (){},
leading: Icon(Icons.storefront_sharp),
hoverColor: Colors.grey,
title: Text("Shop"),
),
Divider(),
ListTile(
onTap: (){},
leading: Icon(Icons.location_on_outlined),
hoverColor: Colors.grey,
title: Text("Map"),
),
Divider(
thickness: 2.0,
),
ListTile(
onTap: (){},
leading: Icon(Icons.settings),
hoverColor: Colors.grey,
title: Text("Settings"),
),
Divider(),
ListTile(
onTap: (){},
leading: Icon(Icons.logout),
hoverColor: Colors.grey,
title: Text("Logout"),
),
],
),
);
The issue is that your context does not contains yet the data from your Scaffold, the workaround you can apply would be to use a GlobalKey to refer to your current ScaffoldState:
class MyWidget extends StatelessWidget {
final _scaffoldKey = GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
backgroundColor: Colors.white,
drawer: CstmDrawer(),
body: SafeArea(
child: Column(
children: [
Row(
children: [
Container(
height: 150.0,
width: MediaQuery.of(context).size.width * 1.0,
child: Stack(
children: [
Container(
height: 130.0,
width: MediaQuery.of(context).size.width * 1.0,
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.vertical(
bottom: Radius.elliptical(
MediaQuery.of(context).size.width, 100.0),
),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
/// Use the _scaffoldKey to call openDrawer()
IconButton(
onPressed: () =>
_scaffoldKey.currentState.openDrawer(),
icon: Icon(Icons.menu),
),
Container(
child: Row(
children: [
IconButton(
onPressed: () {},
icon: Icon(
Icons.notifications_active_outlined)),
IconButton(
onPressed: () {},
icon: Icon(Icons.shopping_cart_outlined)),
],
),
),
],
),
),
Positioned(
bottom: 20.0,
right: MediaQuery.of(context).size.width * 0.07,
child: Container(
height: 40.0,
width: MediaQuery.of(context).size.width * 0.85,
child: Theme(
data: ThemeData(primaryColor: Colors.black),
child: TextField(
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
prefixIcon: Icon(Icons.search),
hintText: "Search Here",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
),
),
),
),
),
],
),
),
],
),
],
),
),
);
}
}
Here the solution is to use _scaffoldKey to call openDrawer() so instead of doing Scaffold.of(context).openDrawer() you will do _scaffoldKey.currentState.openDrawer(), and do not forget to assign the key to your Scaffold, by doing key: _scaffoldKey.
You can use this I guess!
IconButton(
icon: Icon(Icons.menu),
onPressed: () => Scaffold.of(context).openDrawer()
)

How to implement a bottom navigation drawer in Flutter

I'm trying to implement a bottom navigation drawer, similar to the one used in the Reply Material Study, that is an extension of the bottom app bar, and opened and closed via an icon button in the bottom app bar.
I've tried bottom sheets, but that replaces, or hovers on top of, the bottom app bar. I want it to look like the one in the screenshot where the bottom app bar stays on the screen and the bottom navigation drawer slides up when the "menu" button is tapped.
The Material Design site shows this as a component, but doesn't link off to anywhere showing how to implement it in Flutter.
I quickly made it, but you are going to have to implement active page text/icon colors to the listview. Also, the full code is here if you want to copy from the gist.
class ScreenOne extends StatefulWidget {
#override
_ScreenOneState createState() => _ScreenOneState();
}
class _ScreenOneState extends State<ScreenOne> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Reply demo"),
),
bottomNavigationBar: BottomAppBar(
elevation: 0,
color: Color(0xff344955),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10.0),
height: 56.0,
child: Row(children: <Widget>[
IconButton(
onPressed: showMenu,
icon: Icon(Icons.menu),
color: Colors.white,
),
Spacer(),
IconButton(
onPressed: () {},
icon: Icon(Icons.add),
color: Colors.white,
)
]),
),
),
);
}
showMenu() {
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16.0),
topRight: Radius.circular(16.0),
),
color: Color(0xff232f34),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Container(
height: 36,
),
SizedBox(
height: (56 * 6).toDouble(),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16.0),
topRight: Radius.circular(16.0),
),
color: Color(0xff344955),
),
child: Stack(
alignment: Alignment(0, 0),
overflow: Overflow.visible,
children: <Widget>[
Positioned(
top: -36,
child: Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(50)),
border: Border.all(
color: Color(0xff232f34), width: 10)),
child: Center(
child: ClipOval(
child: Image.network(
"https://i.stack.imgur.com/S11YG.jpg?s=64&g=1",
fit: BoxFit.cover,
height: 36,
width: 36,
),
),
),
),
),
Positioned(
child: ListView(
physics: NeverScrollableScrollPhysics(),
children: <Widget>[
ListTile(
title: Text(
"Inbox",
style: TextStyle(color: Colors.white),
),
leading: Icon(
Icons.inbox,
color: Colors.white,
),
onTap: () {},
),
ListTile(
title: Text(
"Starred",
style: TextStyle(color: Colors.white),
),
leading: Icon(
Icons.star_border,
color: Colors.white,
),
onTap: () {},
),
ListTile(
title: Text(
"Sent",
style: TextStyle(color: Colors.white),
),
leading: Icon(
Icons.send,
color: Colors.white,
),
onTap: () {},
),
ListTile(
title: Text(
"Trash",
style: TextStyle(color: Colors.white),
),
leading: Icon(
Icons.delete_outline,
color: Colors.white,
),
onTap: () {},
),
ListTile(
title: Text(
"Spam",
style: TextStyle(color: Colors.white),
),
leading: Icon(
Icons.error,
color: Colors.white,
),
onTap: () {},
),
ListTile(
title: Text(
"Drafts",
style: TextStyle(color: Colors.white),
),
leading: Icon(
Icons.mail_outline,
color: Colors.white,
),
onTap: () {},
),
],
),
)
],
))),
Container(
height: 56,
color: Color(0xff4a6572),
)
],
),
);
});
}
}
You can use BottomSheet . (Thanks to westdabestdb)
Working on flutter_gallery demo app:
class ModalBottomSheetDemo extends StatelessWidget {
static const String routeName = '/material/modal-bottom-sheet';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Modal bottom sheet'),
actions: <Widget>[MaterialDemoDocumentationButton(routeName)],
),
body: Center(
child: RaisedButton(
child: const Text('SHOW BOTTOM SHEET'),
onPressed: () {
showModalBottomSheet<void>(context: context, builder: (BuildContext context) {
return Container(
child: Padding(
padding: const EdgeInsets.all(32.0),
child: Text('This is the modal bottom sheet. Tap anywhere to dismiss.',
textAlign: TextAlign.center,
style: TextStyle(
color: Theme.of(context).accentColor,
fontSize: 24.0
)
)
)
);
});
}
)
)
);
}
}
Building up on westdabestdb's answer and this article:
If you want a bottom navigation drawer that is not blocking, with rounded corners and that is not depending on a black background, try this:
class GoogleMapsHomeUI extends StatelessWidget {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
showBottomDrawer();
return Scaffold(
key: scaffoldKey, // use the key to reference the Scaffold from outside
... the rest of your background Scaffold
);
}
void showBottomDrawer() {
// the next line is needed, because the Scaffold needs to be finished before this function continues.
WidgetsBinding.instance.addPostFrameCallback((_) {
PersistentBottomSheetController? bottomSheetController = scaffoldKey.currentState?.showBottomSheet((BuildContext context) {
return Container(
height: 300,
decoration: BoxDecoration(
borderRadius: BorderRadius.only( // makes the round corners
topLeft: Radius.circular(20.0),
topRight: Radius.circular(20.0),
),
color: Color(0xff232f34),
),
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Container(
height: 36,
),
SizedBox(
height: (56 * 6).toDouble(),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16.0),
topRight: Radius.circular(16.0),
),
color: Color(0xff344955),
),
child: Stack(
alignment: Alignment(0, 0),
children: <Widget>[
Positioned(
top: -36,
child: Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(50)),
border: Border.all(
color: Color(0xff232f34), width: 10)),
child: Center(
child: ClipOval(
child: Image.network(
"https://i.stack.imgur.com/S11YG.jpg?s=64&g=1",
fit: BoxFit.cover,
height: 36,
width: 36,
),
),
),
),
),
Positioned(
child: ListView(
physics: NeverScrollableScrollPhysics(),
children: <Widget>[
ListTile(
title: Text(
"Inbox",
style: TextStyle(color: Colors.white),
),
leading: Icon(
Icons.inbox,
color: Colors.white,
),
onTap: () {},
),
ListTile(
title: Text(
"Starred",
style: TextStyle(color: Colors.white),
),
leading: Icon(
Icons.star_border,
color: Colors.white,
),
onTap: () {},
),
ListTile(
title: Text(
"Sent",
style: TextStyle(color: Colors.white),
),
leading: Icon(
Icons.send,
color: Colors.white,
),
onTap: () {},
),
ListTile(
title: Text(
"Trash",
style: TextStyle(color: Colors.white),
),
leading: Icon(
Icons.delete_outline,
color: Colors.white,
),
onTap: () {},
),
ListTile(
title: Text(
"Spam",
style: TextStyle(color: Colors.white),
),
leading: Icon(
Icons.error,
color: Colors.white,
),
onTap: () {},
),
ListTile(
title: Text(
"Drafts",
style: TextStyle(color: Colors.white),
),
leading: Icon(
Icons.mail_outline,
color: Colors.white,
),
onTap: () {},
),
],
),
)
],
))),
Container(
height: 56,
color: Color(0xff4a6572),
)
],
),
),
),
); // Container
},
backgroundColor: Colors.black,
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(topLeft: Radius.circular(15.0), topRight: Radius.circular(15.0)),
), clipBehavior: null,
enableDrag: true,
);
result (I'm not finished with the background yet, but you can interact with the background, while the drawer is open):