How can I increase drawer drag area width in Flutter? - 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,
),
),
),
),
],
)
],
),
),
),

Related

How Can i Stick a Login Screen?

I am new to flutter. And I'm gaining more and more knowledge in a flutter.
I make A login screen long before for my Project But Someone suggest that your login screen not be scrolled up words should stick in the same position.
Brief about my screen.--
I added singleChildScrollview.I want to stop scrolling
below is my login screen. dart
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
),
body: Center(
child: SingleChildScrollView(
child: Container(
color: Colors.white12,
child: Padding(
padding: const EdgeInsets.all(36.0),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 200,
child: Image.asset(
"assests/man.png",
fit: BoxFit.contain,
)),
SizedBox(height: 45),
emailField,
SizedBox(height: 25),
passwordField,
SizedBox(height: 35),
loginButton,
SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Don't have an account ? "),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
RegistrationScreen()));
// Navigator.push(context, MaterialPageRoute(builder:(context)=>HomeScreen()));
},
child: Text(
"SignUp",
style: TextStyle(
color: Colors.redAccent,
fontWeight: FontWeight.w600,
fontSize: 15,
),
),
)
],
),
],
),
),
),
),
),
),
);
Remove SingleChildScrollview
Like this
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
),
body: Center(
child: Container(
color: Colors.white12,
child: Padding(
padding: const EdgeInsets.all(36.0),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 200,
child: Image.asset(
"assests/man.png",
fit: BoxFit.contain,
)),
SizedBox(height: 45),
emailField,
SizedBox(height: 25),
passwordField,
SizedBox(height: 35),
loginButton,
SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Don't have an account ? "),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
RegistrationScreen()));
// Navigator.push(context, MaterialPageRoute(builder:(context)=>HomeScreen()));
},
child: Text(
"SignUp",
style: TextStyle(
color: Colors.redAccent,
fontWeight: FontWeight.w600,
fontSize: 15,
),
),
)
],
),
],
),
),
),
),
),
);
Add physics to SingleChildScrollView
return SingleChildScrollView(
physics: const NeverScrollableScrollPhysics(),
// rest of the code here
);
Though i would not recommend it as if the screen size is small and if the keyboard opens up, a render overflow will occur.

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

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 to Center GridView Component

Hello I new to Flutter and I am having an issue on centering the components of my icons anyone can suggest the correct way to center the dashboard icons.I am still trying to fix it but if you could provide some pointers for me that would be great. I have tried putting it row to row but the issue still same also padding on the Widget that I created
Widget build(BuildContext context){
final _width = MediaQuery.of(context).size.width;
final _height = MediaQuery.of(context).size.height;
return new Stack(children: <Widget>[
new Container(color: Colors.blue,),
new Scaffold(
appBar: AppBar(
title: Text("Welcome"),
centerTitle: true,
),
drawer: MenuComponent(),
backgroundColor: Colors.transparent,
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Align(
alignment: FractionalOffset.topCenter,
child: Padding(
padding: EdgeInsets.all(10.0),
child: SizedBox(
height: 50,
width: 130,
child:new Text('One', style: new TextStyle(fontWeight: FontWeight.bold, fontSize: _width/15, color: Colors.white),),
),
),
)
),
new Divider(height: _height/30,color: Colors.white,),
],
),
Expanded(
child: Center(
child: GridView.count(
padding: const EdgeInsets.all(20.0),
crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
crossAxisCount: 4,
children: <Widget>[
homePageRowCell(Icons.account_circle, "My Account",context,HomePage()),
homePageRowCell(Icons.dashboard, "Home page",context, HomePage()),
homePageRowCell(Icons.person_outline, "Profile",context, ProfilePage()),
homePageRowCell(Icons.settings, "Settings",context, Settings()),
homePageRowCell(Icons.exit_to_app, "Logout",context, LoginPage()),
],
),
)
)
],
),
),
)
],);
// return Scaffold(
// appBar: AppBar(
// title: Text("Home Page"),
// centerTitle: true,
// ),
// drawer: MenuComponent(),
// );
}
}
Widget homePageRowCell(var sIcon, String title, BuildContext context, var page) => new Container(
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => page)
);
},
child: new Row(
children: <Widget>[
Column(
children: <Widget>[
new Icon(sIcon,color: Colors.white,),
new Text(title,style: new TextStyle(color: Colors.white, fontWeight: FontWeight.normal)),
],
),
],
),
)
);
Please try below code and check output
#override
Widget build(BuildContext context) {
final _width = MediaQuery.of(context).size.width;
final _height = MediaQuery.of(context).size.height;
return new Stack(
children: <Widget>[
new Container(
color: Colors.blue,
),
new Scaffold(
appBar: AppBar(
title: Text("Welcome"),
centerTitle: true,
),
drawer: MenuComponent(),
backgroundColor: Colors.transparent,
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Align(
alignment: FractionalOffset.topCenter,
child: Padding(
padding: EdgeInsets.all(10.0),
child: SizedBox(
height: 50,
width: 130,
child: new Text(
'One',
style: new TextStyle(
fontWeight: FontWeight.bold,
fontSize: _width / 15,
color: Colors.white),
),
),
),
)),
new Divider(
height: _height / 30,
color: Colors.white,
),
],
),
Expanded(
child: Center(
child: GridView.count(
crossAxisCount: 4,
crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
children: <Widget>[
homePageRowCell(Icons.account_circle, "My Account",
context, HomePage()),
homePageRowCell(
Icons.dashboard, "Home page", context, HomePage()),
homePageRowCell(Icons.person_outline, "Profile", context,
ProfilePage()),
homePageRowCell(
Icons.settings, "Settings", context, Settings()),
homePageRowCell(
Icons.exit_to_app, "Logout", context, LoginPage()),
],
),
))
],
),
),
)
],
);
// return Scaffold(
// appBar: AppBar(
// title: Text("Home Page"),
// centerTitle: true,
// ),
// drawer: MenuComponent(),
// );
}
Widget homePageRowCell(
var sIcon, String title, BuildContext context, var page) =>
new Container(
child: GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => page));
},
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Column(
children: <Widget>[
new Icon(
sIcon,
color: Colors.white,
),
new Text(title,
style: new TextStyle(
color: Colors.white, fontWeight: FontWeight.normal)),
],
),
],
),
));

How to make a screen scrollable in Flutter?

In my Flutter project, in one page I have some rows including card align vertically. Now, I want this screen to make scroll-able.
I have tried replacing the column to Listview but it didn't work. I also tried to wrap it with SingleChildScrollview but didn't work. It shows like below image-
Here's the code -
HomeFragment.dart
class HomeFragment extends StatefulWidget {
#override
_HomeFragmentState createState() => new _HomeFragmentState();
}
String jwt;
class _HomeFragmentState extends State<HomeFragment> {
List<LastEngagement> _lastEngagements = List<LastEngagement>();
#override
void initState() {
super.initState();
_getLastEngagement;
_getLastEngagement2();
}
void _getLastEngagement() {
Webservice().load(LastEngagement.allLastEngagement).then((newsArticles) => {
setState(() => {
_lastEngagements = newsArticles
})
});
}
void _getLastEngagement2() {
Webservice().load(LastEngagement.allLastEngagement).then((newsArticles) => {
setState(() => {
_lastEngagements = newsArticles
})
});
}
Card showCard(int index) {
return new Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
CircleAvatar(
backgroundImage: NetworkImage(
"https://randomuser.me/api/portraits/men/1.jpg"
),
),
SizedBox(
width: 10.0,
),
Expanded(child: Text(_lastEngagements[index].title)),
],
),
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('News'),
),
body:Column(
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Container(
color: Colors.blue,
child: SizedBox(
height: 100.0,
child: new ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: _lastEngagements.length,
itemBuilder: (BuildContext ctxt, int index) {
return Container(
width: 200.0,
child: showCard(index),
);
},
),
),
),
),
],
mainAxisAlignment: MainAxisAlignment.spaceBetween,
),
Row(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
child: InkWell(
splashColor: Colors.blue.withAlpha(30),
onTap: () {
print('Card tapped.');
},
child: Container(
height: 100,
child: Text('A card that can be tapped'),
),
),
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
child: InkWell(
splashColor: Colors.blue.withAlpha(30),
onTap: () {
print('Card tapped.');
},
child: Container(
height: 100,
child: Text('A card that can be tapped'),
),
),
),
),
),
],
),
Row(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
child: InkWell(
splashColor: Colors.blue.withAlpha(30),
onTap: () {
print('Card tapped.');
},
child: Container(
height: 100,
child: Text('A card that can be tapped'),
),
),
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
child: InkWell(
splashColor: Colors.blue.withAlpha(30),
onTap: () {
print('Card tapped.');
},
child: Container(
height: 100,
child: Text('A card that can be tapped'),
),
),
),
),
),
],
),
Row(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
child: InkWell(
splashColor: Colors.blue.withAlpha(30),
onTap: () {
print('Card tapped.');
},
child: Container(
height: 100,
child: Text('A card that can be tapped'),
),
),
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
child: InkWell(
splashColor: Colors.blue.withAlpha(30),
onTap: () {
print('Card tapped.');
},
child: Container(
height: 100,
child: Text('A card that can be tapped'),
),
),
),
),
),
],
),
Row(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
child: InkWell(
splashColor: Colors.blue.withAlpha(30),
onTap: () {
print('Card tapped.');
},
child: Container(
height: 100,
child: Text('A card that can be tapped'),
),
),
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
child: InkWell(
splashColor: Colors.blue.withAlpha(30),
onTap: () {
print('Card tapped.');
},
child: Container(
height: 100,
child: Text('A card that can be tapped'),
),
),
),
),
),
],
)
],
)
);
}
}
Replacing the Column by Listview causes following error-
So, I need a permanent solution to make my screen scroll-able, doesn't matter whatever widgets I use.
You can use SingleChildScrollView or change the column widget to ListView
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('News'),
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
],
),
));
}
Or
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('News'),
),
body: ListView(
children: <Widget>[],
));
}
Well the previous answers do contain the solution .. at least that's what I think .. but they are buggy answers and that's why it's not working .. try this
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("News"),
),
body: Column(
children: <Widget>[
Expanded(
child: SingleChildScrollView(),
)
],
),
);
}
The expanded gives SingleChildScrollView() full height of the screen allowing it to work :)
I think it should work . Good luck
SingleChildScrollView(
scrollDirection: Axis.vertical,)
Try this instead.
Try below code:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('News'),
),
body: Column(
children: <Widget>[
Expanded
(
child: SingleChildScrollView()
),
flex: 1,
]
)
);
}