I want to convert a Widget into a StatelessWidget - flutter

I have a Widget to build Cards using the data stored in the Firestore i want to convert this Widget into a StatelessWidget to use the buttons of the Card.
This is the Widget
Widget buildProducts(Products products) => Card(
clipBehavior: Clip.antiAlias,
child: SizedBox(
width: 300,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Image(image: NetworkImage(products.imageUrl)),
ListTile(
title: Text(products.name),
subtitle: Text('Precio: ${products.price} \$'),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 8, 8),
child: ElevatedButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(
const Color(0xFFFFFFFF),
),
backgroundColor: MaterialStateProperty.all<Color>(
const Color(0xFF6750A4),
),
),
onPressed: () => showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) => AlertDialog(
title: const Text('Subir Producto'),
content: const Text(
'El producto ha añadido a la base de datos correctamente'),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('OK'))
],
),
),
child: const Text(
'Añadir al Carro',
),
),
),
],
),
],
),
),
);

Create a StatelessWidget and pass the Products through constructor and paste the card on return section.
class ProductWidet extends StatelessWidget {
final Products products;
const ProductWidet({required this.products,Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Card(
clipBehavior: Clip.antiAlias,
child: SizedBox(
width: 300,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Image(image: NetworkImage(products.imageUrl)),
ListTile(
title: Text(products.name),
subtitle: Text('Precio: ${products.price} \$'),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 8, 8),
child: ElevatedButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(
const Color(0xFFFFFFFF),
),
backgroundColor: MaterialStateProperty.all<Color>(
const Color(0xFF6750A4),
),
),
onPressed: () => showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) => AlertDialog(
title: const Text('Subir Producto'),
content: const Text(
'El producto ha añadido a la base de datos correctamente'),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('OK'))
],
),
),
child: const Text(
'Añadir al Carro',
),
),
),
],
),
],
),
),
);
}
}

Related

Can't turn back to Homescreen (stacked with a Drawerscreen) with WillPopScope

I'm building a language learning app and on my homepage there are specific topics like colors etc. which you can choose and a learning page (via JSON) opens. My problem is that I can't find a solution on how to get back to the Homescreen. It's a Stack.
here's the code from my HomePage class with the Stack:
static const String id = 'home_page';
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
DrawerScreen(),
HomeScreen(),
],
),
);
}
}
I already tried these solutions for my BackButton, but the app either crashes (when using the WillPopScope) or I'm getting a black screen (when using the
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitDown, DeviceOrientation.portraitUp]);
return WillPopScope(
onWillPop: () {
return showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Möchtest du das Quiz beenden?'),
actions: <Widget>[
RaisedButton(
child: Text('Ja'),
onPressed: () =>
Navigator.pushNamed(context, DrawerScreen.id),
),
RaisedButton(
child: Text('Nein'),
onPressed: () => Navigator.of(context).pop(false),
),
]));
},
child: Scaffold(
body: Padding(
padding: const EdgeInsets.fromLTRB(8.0, 64.0, 8.0, 8.0),
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
BackButton(),
],
),
Expanded(
flex: 3,
child: Container(
padding: EdgeInsets.all(15.0),
alignment: Alignment.bottomCenter,
child: Stack(
children: [
AnimatedOpacity(
opacity: opacity1,
duration: Duration(seconds: 1),
child: Center(
child: Text(
mydata[0][i.toString()],
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 48.0,
fontFamily: "Circular",
fontWeight: FontWeight.bold,
),
),
),
),
AnimatedOpacity(
opacity: opacity2,
duration: Duration(seconds: 2),
child: Center(
child: Text(
mydata[1][i.toString()],
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 48.0,
fontFamily: "Circular",
fontWeight: FontWeight.bold,
),
),
),
),
],
),
),
),
Expanded(
flex: 6,
child: AbsorbPointer(
absorbing: disableAnswer,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
choicebutton1('a'),
choicebutton2('b'),
],
),
),
),
),
],
),
),
),
);
}
IconButton(
onPressed: () {
Navigator.of(context).pop();
},
icon: Icon(
Icons.arrow_back,
size: 30,
color: Colors.black,
),
),
onPressed: () => Navigator.of(context).pop(false)
remove the false

how to create add minus button on my product in flutter?

May I know how to create a function that displays the value and have the button remove and add to the product list? I already create an icon button for remove and add to the screen but I do not have any clues on how to use the button.
GUI on application:
my aim is to have this kind of button:
my full code for this GUI:
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'CartList.dart';
import 'bottom_navi_iconW.dart';
import 'globals.dart' as globals;
class SarapanPagi extends StatefulWidget {
final List list;
final int index;
final String category;
SarapanPagi({this.index,this.list,this.category});
#override
_SarapanPagiState createState() => _SarapanPagiState();
}
class _SarapanPagiState extends State<SarapanPagi> {
Future<List> getData() async{
var url = 'http://10.0.2.2/foodsystem/breakfastlist.php';
var data = {
'product_type': globals.jenisCategory,
'product_owner': widget.list[widget.index]['restaurant_id'],
};
var response = await http.post(url, body: json.encode(data));
//final response= await http.get("http://10.0.2.2/foodsystem/getdata.php");
return json.decode(response.body);}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
iconTheme: IconThemeData(color: Colors.black),
title: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
//Text("Restaurant's Owner Page"),
Text(widget.list[widget.index]['restaurant_name'], textAlign: TextAlign.center, style: TextStyle(fontWeight: FontWeight.w700), ),
],
),
centerTitle: false,
//automaticallyImplyLeading: false,
),
body:
Padding(
padding: const EdgeInsets.only(bottom: 0, left: 5, right: 5),
child: Column(
children: [
/*FloatingActionButton(
onPressed: (){
return showDialog(
context: context,
builder: (context){
return AlertDialog(
content: Text(
globals.jenisCategory
),
);
},
);
},
),*/
//SizedBox(height: 30,),
Container(
//decoration: BoxDecoration(border: Border.all(color: Colors.black, width: 4), borderRadius: BorderRadius.circular(15)),
height: 627,
child: FutureBuilder<List>(
future: getData(),
builder: (context, snapshot){
if(snapshot.hasError) print(snapshot.error);
return snapshot.hasData ?
ItemList(list: snapshot.data,) :
Center(child: CircularProgressIndicator(),);
},
),
),
],
),
),
bottomNavigationBar:
Container(
height: 70,
color: Colors.red,
child: BottomNavIcon(
onTap: (){
Navigator.of(context).push(new MaterialPageRoute(
builder: (BuildContext context)=> new CartListItem()),);
},
image: "troli.png",
name: "CART",
),
),
);
}
}
class ItemList extends StatelessWidget {
final List list;
ItemList({this.list});
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Container(
//color: Colors.red.shade100,
height: 627,
child: ListView.builder(
itemCount: list==null ? 0 : list.length,
itemBuilder: (context, i){
return new Container(
//decoration: BoxDecoration(border: Border.all(color: Colors.blue, width: 4), borderRadius: BorderRadius.circular(15)),
height: 250,
child: new GestureDetector(
onTap: (){},
child: new Card(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
children: [
Padding(
padding: const EdgeInsets.only(bottom : 5.0),
child: Text(list[i]["product_name"], textAlign: TextAlign.center, style: TextStyle(fontSize: 23, fontWeight: FontWeight.bold),),
),
Row(
children: [
//Text(list[i]["product_name"], textAlign: TextAlign.center, style: TextStyle(fontSize: 30),),
Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset(
"menulist/${list[i]['image']}",
width: 150,
height: 150,
),
),
Padding(
padding: const EdgeInsets.only(left: 20.0, bottom: 0),
child:
Column(
children: [
//Text(list[i]["product_name"], textAlign: TextAlign.center, style: TextStyle(fontSize: 30),),
Text("Price RM : ${list[i]["product_price"]}", textAlign: TextAlign.center, style: TextStyle(fontSize: 25),),
Row(
children: [
IconButton(
icon: Icon(Icons.remove),
onPressed: (){},
iconSize: 15,
),
IconButton(
icon: Icon(Icons.add),
onPressed: (){},
iconSize: 15,
),
],
),
RaisedButton(
shape: RoundedRectangleBorder(borderRadius: new BorderRadius.circular(40.0)),
color: Colors.red.shade300,
child: Text("Add to Cart", style: TextStyle(fontWeight: FontWeight.bold),),
onPressed: (){},
)
],
),
),
],
),
],
),
/*ListTile(
title: Text(list[i]["product_name"], textAlign: TextAlign.center, style: TextStyle(fontSize: 30),),
leading:
Image.asset(
"images/${list[i]['image']}",
width: 100,
height: 100,
),
subtitle: Text("Price RM : ${list[i]["product_price"]}", textAlign: TextAlign.center, style: TextStyle(fontSize: 25),),
),*/
],
),
),
),
);
},
),
),
);
}
}
First of all you need to change it to StatefulWidget, since the UI interaction is rendered (changed price). Then something like
onPressed: () => setState(() => list[i]["product_price"] += unitprice),
will do

How to create a vertical scrolling menu effect in Flutter

this question is an improvement for this question. In this case, I would like to reproduce the vertical menu the you can see on the left side of this we base. If you click the link relative to the example on the left you see a number of menu. For instance, clicking on Base you are going to see a vertical menu appearing and disappearing. I would like to know how to reproduce it as well. An example code would be really appreciated.
Thanks all
You can achieve this by simply using a StatefulWidget & managing the hide/show functionality using a boolean value.
Here is the updated code:
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatefulWidget {
#override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget>
with SingleTickerProviderStateMixin {
final colors = <Color>[Colors.indigo, Colors.blue, Colors.orange, Colors.red];
double _size = 250.0;
bool _large = true;
void _updateSize() {
setState(() {
_size = _large ? 250.0 : 0.0;
_large = !_large;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Row(
children: [
AnimatedSize(
curve: Curves.easeIn,
vsync: this,
duration: Duration(seconds: 1),
child: LeftDrawer(size: _size)),
Expanded(
flex: 4,
child: Container(
child: Column(
children: [
Container(
color: Colors.white,
padding: const EdgeInsets.all(8),
child: Row(
children: [
IconButton(
icon: Icon(Icons.menu, color: Colors.black87),
onPressed: () {
_updateSize();
},
),
FlatButton(
child: Text(
'Dashboard',
style: const TextStyle(color: Colors.black87),
),
onPressed: () {},
),
FlatButton(
child: Text(
'User',
style: const TextStyle(color: Colors.black87),
),
onPressed: () {},
),
FlatButton(
child: Text(
'Settings',
style: const TextStyle(color: Colors.black87),
),
onPressed: () {},
),
const Spacer(),
IconButton(
icon: Icon(Icons.brightness_3, color: Colors.black87),
onPressed: () {},
),
IconButton(
icon: Icon(Icons.notification_important,
color: Colors.black87),
onPressed: () {},
),
CircleAvatar(),
],
),
),
Container(
height: 1,
color: Colors.black12,
),
Card(
margin: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
child: Container(
color: Colors.white,
padding: const EdgeInsets.all(20),
child: Row(
children: [
Text(
'Home / Admin / Dashboard',
style: const TextStyle(color: Colors.black),
),
],
),
),
),
Expanded(
child: ListView(
children: [
Row(
children: [
_container(0),
_container(1),
_container(2),
_container(3),
],
),
Container(
height: 400,
color: Color(0xFFE7E7E7),
padding: const EdgeInsets.all(16),
child: Card(
color: Colors.white,
child: Container(
padding: const EdgeInsets.all(16),
child: Text(
'Traffic',
style: const TextStyle(color: Colors.black87),
),
),
),
),
],
),
),
],
),
),
),
],
),
);
}
Widget _container(int index) {
return Expanded(
child: Container(
padding: const EdgeInsets.all(20),
color: Color(0xFFE7E7E7),
child: Card(
color: Color(0xFFE7E7E7),
child: Container(
color: colors[index],
width: 250,
height: 140,
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Text(
'9.823',
style: TextStyle(fontSize: 24),
)),
Icon(Icons.more_vert),
],
),
Text('Members online')
],
),
),
),
),
);
}
}
class LeftDrawer extends StatefulWidget {
LeftDrawer({
Key key,
this.size,
}) : super(key: key);
final double size;
#override
_LeftDrawerState createState() => _LeftDrawerState();
}
class _LeftDrawerState extends State<LeftDrawer> {
bool dropdownVisible = false;
#override
Widget build(BuildContext context) {
return Expanded(
flex: 1,
child: Container(
width: widget.size,
color: const Color(0xFF2C3C56),
child: ListView(
children: [
Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(16),
color: Color(0xFF223047),
child: Text('CORE UI'),
),
_tile('Dashboard'),
Container(
padding: const EdgeInsets.only(left: 10),
margin: const EdgeInsets.only(top: 30),
child: Text('THEME',
style: TextStyle(
color: Colors.white54,
))),
_tile('Colors'),
_tile('Typography'),
_tileDropdown('Base'),
_tile('Buttons'),
],
),
),
);
}
Widget _tile(String label) {
return ListTile(
title: Text(label),
onTap: () {},
);
}
Widget _option(String label) {
return ListTile(
tileColor: Color(0xFF223047),
contentPadding: const EdgeInsets.only(left: 40),
title: Text(label),
onTap: () {},
);
}
Widget _tileDropdown(String label) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
title: Text(label),
onTap: () {
setState(() {
dropdownVisible = !dropdownVisible;
});
},
trailing: dropdownVisible
? Icon(Icons.arrow_drop_up)
: Icon(Icons.chevron_left),
),
Visibility(
visible: dropdownVisible,
child: _option('Breadcrumbs'),
),
Visibility(
visible: dropdownVisible,
child: _option('Cloud'),
),
Visibility(
visible: dropdownVisible,
child: _option('Carousel'),
),
Visibility(
visible: dropdownVisible,
child: _option('Collapse'),
),
],
);
}
}

Drawer footer items

i have some little trouble with the drawer , i've searched on stack a solution for this , and found a solution , but after trying it out , it didnt work for me ! :) the idea is , i want to have some items in drawers displayed in the very end of it ! :)
Drawer(
child: Container(
decoration: BoxDecoration(color: Color(0xFF0098c2)),
child: ListView(
children: <Widget>[
ListTile(
title: Text(
'Dealer',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
leading: Icon(
Icons.person,
size: 20.0,
color: Colors.white,
),
onTap: () {
Navigator.pop(context);
Navigator.of(context).push(new MaterialPageRoute(
builder: (context) => dealerBuilder()));
},
),
ListTile(
title: Text(
'Shuffler',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
leading: Icon(
Icons.shuffle,
size: 20.0,
color: Colors.white,
),
onTap: () {
Navigator.pop(context);
Navigator.of(context).push(new MaterialPageRoute(
builder: (context) => shufflerBuilder()));
},
),
ListTile(
title: Text(
'Mistakes',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
leading: Icon(
Icons.info_outline,
size: 20.0,
color: Colors.white,
),
onTap: () {
Navigator.pop(context);
Navigator.of(context).push(new MaterialPageRoute(
builder: (context) => mistakePage()));
},
),
ListTile(
title: Text(
'Important links',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
leading: Icon(
Icons.border_color,
size: 20.0,
color: Colors.white,
),
onTap: () {
Navigator.of(context).push(new MaterialPageRoute(
builder: (context) => importantLinks()));
},
),
Container(
child: Align(
alignment: FractionalOffset.bottomCenter,
child: Column(
children: <Widget>[
Divider(),
ListTile(
leading: Icon(Icons.settings),
title: Text('Facebook')),
ListTile(
leading: Icon(Icons.help),
title: Text('Instagram'))
],
))),
],
),
),
),
thats the code that i've got in my drawer , so far its displaying this way !
You can copy paste run full code below
You can replace ListView with Column and wrap first group with Expaned Column
child: Column(
children: <Widget>[
Expanded(
child: Column(children: <Widget>[
...
Container(
child: Align(
working demo
full code
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
drawer: Drawer(
child: Container(
decoration: BoxDecoration(color: Color(0xFF0098c2)),
child: Column(
children: <Widget>[
Expanded(
child: Column(children: <Widget>[
ListTile(
title: Text(
'Dealer',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
leading: Icon(
Icons.person,
size: 20.0,
color: Colors.white,
),
onTap: () {
/* Navigator.pop(context);
Navigator.of(context).push(new MaterialPageRoute(
builder: (context) => dealerBuilder()));*/
},
),
ListTile(
title: Text(
'Shuffler',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
leading: Icon(
Icons.shuffle,
size: 20.0,
color: Colors.white,
),
onTap: () {
/*Navigator.pop(context);
Navigator.of(context).push(new MaterialPageRoute(
builder: (context) => shufflerBuilder()));*/
},
),
ListTile(
title: Text(
'Mistakes',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
leading: Icon(
Icons.info_outline,
size: 20.0,
color: Colors.white,
),
onTap: () {
/* Navigator.pop(context);
Navigator.of(context).push(new MaterialPageRoute(
builder: (context) => mistakePage()));*/
},
),
ListTile(
title: Text(
'Important links',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
leading: Icon(
Icons.border_color,
size: 20.0,
color: Colors.white,
),
onTap: () {
/*Navigator.of(context).push(new MaterialPageRoute(
builder: (context) => importantLinks()));*/
},
),
]),
),
Container(
child: Align(
alignment: FractionalOffset.bottomCenter,
child: Column(
children: <Widget>[
Divider(),
ListTile(
leading: Icon(Icons.settings),
title: Text('Facebook')),
ListTile(
leading: Icon(Icons.help),
title: Text('Instagram'))
],
))),
],
),
),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
),
);
}
}
Try this:
Drawer(
child: Container(
decoration: BoxDecoration(color: Color(0xFF0098c2)),
child: ListView(
children: <Widget>[
ListTile(
title: Text(
'Dealer',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
leading: Icon(
Icons.person,
size: 20.0,
color: Colors.white,
),
onTap: () {
Navigator.pop(context);
Navigator.of(context).push(new MaterialPageRoute(
builder: (context) => dealerBuilder()));
},
),
ListTile(
title: Text(
'Shuffler',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
leading: Icon(
Icons.shuffle,
size: 20.0,
color: Colors.white,
),
onTap: () {
Navigator.pop(context);
Navigator.of(context).push(new MaterialPageRoute(
builder: (context) => shufflerBuilder()));
},
),
ListTile(
title: Text(
'Mistakes',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
leading: Icon(
Icons.info_outline,
size: 20.0,
color: Colors.white,
),
onTap: () {
Navigator.pop(context);
Navigator.of(context).push(new MaterialPageRoute(
builder: (context) => mistakePage()));
},
),
ListTile(
title: Text(
'Important links',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
leading: Icon(
Icons.border_color,
size: 20.0,
color: Colors.white,
),
onTap: () {
Navigator.of(context).push(new MaterialPageRoute(
builder: (context) => importantLinks()));
},
),
Expanded(),
Container(
child: Align(
alignment: FractionalOffset.bottomCenter,
child: Column(
children: <Widget>[
Divider(),
ListTile(
leading: Icon(Icons.settings),
title: Text('Facebook')),
ListTile(
leading: Icon(Icons.help),
title: Text('Instagram'))
],
))),
],
),
),
),
Here is a way of doing it
Code:
Scaffold(
appBar: AppBar(),
drawer: Drawer(
child: LayoutBuilder(
builder: (context, constraints) {
return SingleChildScrollView(
child: Container(
decoration: BoxDecoration(color: Color(0xFF0098c2)),
child: ConstrainedBox(
constraints: constraints.copyWith(
minHeight: constraints.maxHeight,
maxHeight: double.infinity,
),
child: IntrinsicHeight(
child: SafeArea(
child: Column(
children: [
Column(
children: <Widget>[
// your ListTile here
],
),
Expanded(
child: Align(
alignment: Alignment.bottomLeft,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// your footer widgets here
],
),
),
)
],
),
),
),
),
),
);
},
),
),
body: Container(),
);
By using LayoutBuilder, ConstrainedBox and IntrinsicHeight you are going to be able to use Expanded even inside a ScrollView and keep your image footer at the bottom. It ensure you to have a responsive layout on any phone screen.
Result in image:
Full test code used
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: MyWidget(),
);
}
}
class MyWidget extends StatefulWidget {
#override
State<StatefulWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
drawer: Drawer(
child: LayoutBuilder(
builder: (context, constraints) {
return SingleChildScrollView(
child: Container(
decoration: BoxDecoration(color: Color(0xFF0098c2)),
child: ConstrainedBox(
constraints: constraints.copyWith(
minHeight: constraints.maxHeight,
maxHeight: double.infinity,
),
child: IntrinsicHeight(
child: SafeArea(
child: Column(
children: [
Column(
children: <Widget>[
...List<Widget>.generate(
5,
(index) => ListTile(
title: Text(
"$index",
style: TextStyle(color: Colors.white),
),
leading: Icon(
Icons.person,
size: 20,
color: Colors.white,
),
onTap: () => Navigator.pop(context),
)),
],
),
Expanded(
child: Align(
alignment: Alignment.bottomLeft,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
leading: Icon(Icons.settings),
title: Text('Facebook'),
onTap: () => Navigator.pop(context),
),
ListTile(
leading: Icon(Icons.help),
title: Text('Instagram'),
onTap: () => Navigator.pop(context),
),
],
),
),
)
],
),
),
),
),
),
);
},
),
),
body: Container(),
);
}
}
Expanded on SizedBox works for me!
class CustomDrawer extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Drawer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
DrawerHeader(child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
// SizedBox(height: 10,),
Padding(
padding: const EdgeInsets.all(10.0),
child: ProfileAvatar(),
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
children: [
Text("Syed Tariq Ullah"),
Spacer(),
IconButton(onPressed: (){},
icon:Icon(CupertinoIcons.play_arrow)),
],
),
),
],)),
SizedBox(height: 5.0,),
ListTile(
leading: Icon(CupertinoIcons.chat_bubble_2_fill),
title: Text("Messages"),
),
ListTile(
leading: Icon(CupertinoIcons.chart_bar),
title: Text("Stats"),
),
ListTile(
leading: Icon(CupertinoIcons.briefcase),
title: Text("Your Content"),
),
ListTile(
leading: Icon(CupertinoIcons.bookmark),
title: Text("Bookmarks"),
),
ListTile(
leading: Icon(CupertinoIcons.doc_text),
title: Text("Drafts"),
),
Divider(height: 2.0,),
Expanded(child: SizedBox(height: 20,)),
Align(
alignment: Alignment.bottomCenter,
child: ListTile(leading: Icon(CupertinoIcons.settings_solid),
title: Text("Settings"),
trailing: Icon(CupertinoIcons.ellipsis),
),
),
// Spacer(),
],),
);
}
}
You can use Scaffold. If you want a header that doesn't move, you can set appBar to a PreferredSize widget with the child as DrawerHeader or whatever you want. Set body to ListView for a scrollable list. And set bottomNavigationBar to Container with some height (say 144 for 3 buttons), then the child to a Column widget.
return Drawer(
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(144),
child: DrawerHeader(child: Image.asset("")),
),
body: ListView(
children: [
ListTile(
title: const Text("dark mode"),
leading: const Icon(Icons.dark_mode_rounded),
trailing: Switch(
value: true,
onChanged: (value) {},
),
),
ListTile(
title: const Text("metric"),
leading: const Icon(Icons.thermostat_rounded),
trailing: Switch(
value: true,
onChanged: (value) {}
),
),
],
),
bottomNavigationBar: Container(
height: 144,
child: Column(
children: [
ListTile(
title: Text("Settings"),
leading: Icon(Icons.settings_outlined),
onTap: () {},
),
ListTile(
title: Text("Help"),
leading: Icon(Icons.help_outline_outlined),
onTap: () {},
),
ListTile(
title: Text("Log Out"),
leading: Icon(Icons.logout_outlined),
onTap: () {},
),
],
),
)),
);
hey I think I figured out the answer it might help -
you can use a spacer widget that occupies all the streched space spaces

How can I increase drawer drag area width in Flutter?

I have a drawer in my Flutter app, but the default drawer has a very small drag area to show it. How can I increase it?
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Scaffold(
drawerDragStartBehavior: DragStartBehavior.down,
drawer: Drawer(
child: Column(
children: <Widget>[
UserAccountsDrawerHeader(
accountName: Text(
fullName ?? "",
style: TextStyle(
color: Colors.white,
letterSpacing: 1.0,
fontSize: 16.0,
),
),
You can simply use the drawerEdgeDragWidth property of the Scaffold:
return Scaffold(
appBar: MyAppBar(),
drawer: MyDrawer(),
// Put the width you want here
// In this case the drag area fills the whole screen
drawerEdgeDragWidth: MediaQuery.of(context).size.width,
body: MyBody(),
);
drawer: SizedBox(
width: MediaQuery.of(context).size.width/1.2,
child: Drawer(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(
height: 10,
),
ListTile(
dense: true,
title: Text(
"Apply for Leave",
style: drawerFont,
),
onTap: () {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ApplyLeave()));
},
),
ListTile(
dense: true,
title: Text(
"Approval for Bills",
style: drawerFont,
),
onTap: () {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ApplyBill()));
},
)
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Container(
color: Colors.grey[200],
width: double.infinity,
height: 60,
child: Padding(
padding: const EdgeInsets.only(
left: 28.0, top: 15, bottom: 15),
child: GestureDetector(
onTap: () {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ContactUs()));
},
child: Text(
"Contact Us",
style: drawerFont,
),
),
),
),
],
)
],
),
),
),