Divide screen into 4 different parts evenly - flutter

I am trying to make this type of layout
but I am getting this layout
I had tried the fitted box and expanded class as well.
My current code :
Home.dart
class HomeScreen extends StatefulWidget {
#override
State<StatefulWidget> createState() {
HomeScreen_Page homecreatestate() => HomeScreen_Page();
return homecreatestate();
}
}
class HomeScreen_Page extends State<HomeScreen> {
#override
Widget build(BuildContext context) {
// TODO: implement build
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text('Home'),
backgroundColor: primarycolor,
),
drawer: new Drawer(
child: new ListView(
children: <Widget>[
new UserAccountsDrawerHeader(
accountName: new Text('Ayub Baba'),
accountEmail: new Text('ayubbabants#gmail.com'),
currentAccountPicture: new CircleAvatar(
child: new Text(
'A',
style: new TextStyle(fontSize: 20.0, color: Colors.white),
),
backgroundColor: secondarycolor,
),
decoration: new BoxDecoration(color: primarycolor),
),
new ListTile(
title: new Text('Profile'),
trailing: new Icon(Icons.account_circle),
),
new ListTile(
title: new Text('Contact Us'),
trailing: new Icon(Icons.contact_mail),
),
new ListTile(
title: new Text('Help'),
trailing: new Icon(Icons.help_outline),
),
new ListTile(
trailing: new Icon(Icons.subdirectory_arrow_left),
title: new Text('LogOut'),
)
],
),
),
body: new Builder(builder: (BuildContext context) {
return new Stack(
fit: StackFit.expand,
children: <Widget>[
new Image.asset(
'assets/bg.png',
fit: BoxFit.cover,
),
new Center(
child: new GridView.count(crossAxisCount: 2,
children: <Widget>[
new Center(
child: new Column(
children: <Widget>[
new Text('Send'),
new Text('(Send a courier)')
],
),
),
new Center(
child: new Column(
children: <Widget>[
new Text('Receive'),
new Text('(Track Your Courier)')
],
),
),
new Center(
child: new Column(
children: <Widget>[
new Text('Shopping'),
new Text('(Online Shopping)')
],
),
),
new Center(
child: new Column(
children: <Widget>[
new Text('Payments Bills'),
new Text('(Eletricity,recharges etc)')
],
),
)
],),
)
],
);
}),
),
);
}
}

There are a few approaches. You can do it with Row/Column + crossAxisAlignment.stretch + Expanded
Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: Container(
color: Colors.red,
),
),
Expanded(
child: Container(
color: Colors.yellow,
),
),
],
),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: Container(
color: Colors.purple,
),
),
Expanded(
child: Container(
color: Colors.black,
),
),
],
),
),
],
);
Or with GridView and LayoutBuilder
return LayoutBuilder(
builder: (context, constraint) {
return new GridView.builder(
itemCount: 4,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: constraint.maxWidth / constraint.maxHeight,
),
itemBuilder: (context, index) {
return Container(
color: Colors.red,
margin: EdgeInsets.all(4.0),
);
},
);
},
);

You can use a GridView and set crossAxisCount to 2. (See Flutter)
new GridView.count(
primary: false,
padding: const EdgeInsets.all(20.0),
crossAxisSpacing: 10.0,
crossAxisCount: 2,
children: <Widget>[
const Text('He\'d have you all unravel at the'),
const Text('Heed not the rabble'),
const Text('Sound of screams but the'),
const Text('Who scream'),
const Text('Revolution is coming...'),
const Text('Revolution, they...'),
],
),

Related

How to make a Card lies between Body in flutter

Anybody how to do the layout similar to the image? I am having difficulty on the CardView and it position is lies between the body. I am still consider quite new to Flutter, having some difficulty in UI part. Full code is as below:
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: PreferredSize(
preferredSize: Size.fromHeight(45.0),
child: AppBar(
automaticallyImplyLeading: false,
elevation: 0.0,
centerTitle: true,
backgroundColor: Color(0xFFED2849),
leading: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
margin: const EdgeInsets.only(left: 8.0),
child: GestureDetector(
onTap: (){
Navigator.of(context).pop(null);
},
child: Image.asset('assets/ic_user_title_back.png', width: 12.0, height: 12.0,),
),
),
],
),
title: Center(
child: Container(
child: Text(
'账号中心',
style: TextStyle(color: Color(0xFFFFFFFF), fontSize: 14),
),
),
),
actions: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
child: GestureDetector(
onTap: (){
//logout
},
child: Text(
'退出登陆',
style: TextStyle(color: Color(0xFFFFFFFF), fontSize: 11),
),
),
),
],
),
)
],
)
),
body: SafeArea(
top: false,
child: Material(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 3,
child: Container(
color: Color(0xFFED2849),
),
),
Expanded(
flex: 7,
child: Container(
color: Color(0xFFF1F1F1),
),
)
],
),
),
)
);
}
You can do this using Stack
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Stack(
// fit: StackFit.expand,
children: [
Column(
children: [
Expanded(
flex: 3,
child : Container(color: Colors.red)
),
Expanded(
flex: 7,
child: Container(
color : Colors.white)
)
]
),
Positioned(
top: MediaQuery.of(context).size.height * 0.2,
left: 20,
right: 20,
child:Card(
child: Padding(
padding : const EdgeInsets.all(16),
child: Text("Your Text here", ),
),)
)
],
)
Try using Stack() it will allow you to overlap several children in a simple way.

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

Column/Scrollview not showing after i made a fixed bottom bar

Apparently i tried to make a bottom button for checkout and it seems to be affecting how the body of the app is working. This only happened after i added the bottomnavbar padding etc
heres the link for the snip: https://imgur.com/a/sDhqasr
class _State extends State<CartOverviewScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Your Cart'),
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Center(child: Text('HI!'),)
],
),
),
bottomNavigationBar: Padding(
padding: EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Card(
margin: EdgeInsets.all(15),
child: Padding(
padding: EdgeInsets.all(8),
child: Row(
children: <Widget>[
Text(
'Total',
style: TextStyle(
fontSize: 20,
),
),
SizedBox(width: 10,),
Chip(label: Text('\$0.00'),)
],
),
),
),
ButtonTheme(
minWidth: double.infinity,
child: RaisedButton(
elevation: 8,
onPressed: () {},
color: colorCustom,
textColor: Colors.white,
child: Text('Checkout'),
),
),
],
),
),
);
}
}
you can also try this
class _State extends State<stat> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Your Cart'),
),
body: Column(
children: <Widget>[
Expanded(
child: Center(
child: Text("Hi"),
),
)
],
),
bottomNavigationBar: Padding(
padding: EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Card(
margin: EdgeInsets.all(15),
child: Padding(
padding: EdgeInsets.all(8),
child: Row(
children: <Widget>[
Text(
'Total',
style: TextStyle(
fontSize: 20,
),
),
SizedBox(
width: 10,
),
Chip(
label: Text('\$0.00'),
)
],
),
),
),
ButtonTheme(
minWidth: double.infinity,
child: RaisedButton(
elevation: 8,
onPressed: () {},
color: Colors.red,
textColor: Colors.white,
child: Text('Checkout'),
),
),
],
),
),
);
}
}
Ahh i found my own answer actually, the problem was caused by bottomNavigationBar hogging the entire body of the app. i just needed to place the following code from below onto the bottomNavigationBar Column.
mainAxisSize: MainAxisSize.min

How to make a container with tabview & listview occupy space upto bottom

I have implemented tab layout which consists of two tabs, each tab view has a listview, container with tabview & listview should occupy space upto bottom as of now i place static value of 400, so only up to 400 the listview appears, i need the list view to be appeared up to bottom. can you please me to fix this
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left:20.0,right:20.0),
child: Container(
color: Colors.white,
child: new TabBar(
controller: _controller,
labelColor: Colors.deepOrange,
tabs: [
new Tab(
icon: const Icon(Icons.description),
text: 'ABC',
),
new Tab(
icon: const Icon(Icons.assignment),
text: 'XYZ',
),
],
),
),
),
Padding(
padding: const EdgeInsets.only(left:20.0,right:20.0),
child: Container(
color: Colors.white,
height: 400.0,
child: new TabBarView(
controller: _controller,
children: <Widget>[
ListView(
children: <Widget>[
ListTile(
title: Text('Sun'),
),
ListTile(
title: Text('Moon'),
),
ListTile(
title: Text('Star'),
),
],
),
ListView(
children: <Widget>[
ListTile(
title: Text('Sun'),
),
ListTile(
title: Text('Moon'),
),
ListTile(
title: Text('Star'),
),
],
),
],
),
),
),
],
),
);
}
I have Used Expanded & Flex Widgets which solved the problem
#override
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.only(left:20.0,right:20.0),
child: Container(
color: Colors.white,
child: new TabBar(
controller: _controller,
labelColor: Colors.deepOrange,
tabs: [
new Tab(
icon: const Icon(Icons.description),
text: 'Current Openings',
),
new Tab(
icon: const Icon(Icons.assignment),
text: 'Applied Jobs',
),
],
),
),
),
flex: 1,
),
Expanded(
child: Padding(
padding: const EdgeInsets.only(left:20.0,right:20.0,bottom: 10.0),
child: Container(
color: Colors.white,
child: new TabBarView(
controller: _controller,
children: <Widget>[
ListView(
children: <Widget>[
ListTile(
title: Text('Sun'),
),
],
),
ListView(
children: <Widget>[
ListTile(
title: Text('Sun'),
),
],
),
],
),
),
),
flex: 9,
),
],
),
);
}

A RenderFlex overflowed by 620 pixels on the bottom

******Update ********
Here's the updated body which resolved the scrolling issue as posted earlier below, but now getting A RenderFlex overflowed by 620 pixels on the bottom. I replaced body: listView with body: Column. I know this is very common issue and per the logcat the solution is to wrap the content in Expanded widget. In my case, I would like to know where to use 'Expanded` widget to resolve the issue.
Widget reviewsSection = Container(
child: FutureBuilder(
future: _fetchReviews(),
builder: (context, snapshot) {
if (snapshot.data != null) {
return _buildReviewTiles(snapshot.data);
} else if (snapshot.hasError) {
return Text('${snapshot.error}',
style: TextStyle(color: Colors.black, fontSize: 12.0),
textAlign: TextAlign.justify);
}
// By default, show a loading spinner
return new Container(child: new CircularProgressIndicator());
}));
// Creates a list view based on the reviews in the reviewList.
Widget _buildReviewTiles(List<Review> list) {
return (new Container(
child: ListView.builder(
shrinkWrap: true,
itemCount: reviewList == null ? 0 : reviewList.length,
itemBuilder: (BuildContext context, int index) {
return new Container(
child: Center(
child: Column(children: <Widget>[
_getReviewTile(reviewList[index]),
new Padding(
padding: EdgeInsets.all(5.0),
),
new Divider(
height: 3.0,
color: Colors.black26,
)
])));
}),
));
}
// Returns a list tile representation of a review
Widget _getReviewTile(Review review) {
// Keep only the day, month, and year
var date = review.created.split(" ")[0];
return new Container(
color: Colors.yellow,
child: new Row(
children: <Widget>[
new Expanded(
child: ListTile(
leading: new Column(children: <Widget>[
const Icon(Icons.stars),
]),
subtitle: new Text(
'${review.review}',
style: TextStyle(color: Colors.black, fontSize: 14.0),
),
title: new Row(
children: <Widget>[
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Text(date, style: new TextStyle(fontSize: 12.0)),
new Padding(
padding: EdgeInsets.all(4.0),
),
],
),
),
new Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
new StarRating(
starCount: 5,
rating: review.rating + 0.0,
color: Colors.amber,
),
]),
],
),
),
),
],
),
);
}
This is my Scaffold code that uses reviewsSection along with other sections:
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
expandedHeight: 200.0,
floating: false,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
background: FadeInImage.assetNetwork(
placeholder: 'assets/header_bg.png',
width: 600.0,
height: 240.0,
fit: BoxFit.cover,
image: 'https:' + pro.profilePhoto),
),
),
];
},
body: Column(
children: <Widget>[
new Container(
color: Colors.black87,
child: Row(
children: <Widget>[
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: new EdgeInsets.fromLTRB(5.0, 8.0, 10.0, 5.0),
),
new Text(
'${pro.fullname}',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
new Text(
'${pro.company}',
style: TextStyle(fontSize: 14.0, color: Colors.white),
),
Padding(
padding: EdgeInsets.all(5.0),
)
],
),
),
new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: new EdgeInsets.fromLTRB(5.0, 8.0, 10.0, 5.0),
),
new StarRating(
starCount: 5,
rating: pro.rating,
color: Colors.amber,
),
new Text(
'${pro.reviewCount} reviews',
style: TextStyle(fontSize: 14.0, color: Colors.white),
),
Padding(
padding: EdgeInsets.all(5.0),
)
],
),
],
),
),
Padding(
padding: EdgeInsets.all(5.0),
),
buttonSection,
Padding(
padding: EdgeInsets.all(2.0),
),
Divider(color: Colors.black26, height: 0.5),
Padding(
padding: EdgeInsets.all(4.0),
),
experienceSection,
Padding(
padding: EdgeInsets.all(8.0),
),
reviewsSection
],
),
),
);
}
Am re-posting the answer suggested by #anmol.majhail that helped me to resolve the issue.
"Try Wraping - reviewsSection in Expanded.& Remove containers around FutureBuilder & ListViewBuilder"
So corrected reviewsSection code that worked is:
Widget reviewsSection = Expanded(
child: FutureBuilder(
future: _fetchReviews(),
builder: (context, snapshot) {
if (snapshot.data != null) {
return _buildReviewTiles(snapshot.data);
} else if (snapshot.hasError) {
return Text('${snapshot.error}',
style: TextStyle(color: Colors.black, fontSize: 12.0),
textAlign: TextAlign.justify);
}
// By default, show a loading spinner
return Center(child: CircularProgressIndicator());
}));