Flutter/Dart - Vertically Centre Gridview - flutter

I am trying to centre a gridview in the centre of my scaffold but I am struggling to achieve this. I have tried wrapping in a Container with the alignment arguments as well as in a column and centre widgets. I have only been able to align my gridview in the centre horizontally. Can someone help? Here is my code:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("My gridview"),
),
body: Center(
child: Padding(
padding: const EdgeInsets.only(left: 50, right: 50),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: MediaQuery.of(context).size.height * 0.4,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: Container(
height: double.infinity,
child: Center(
child: Text("Row Item 1"),
),
),
),
Expanded(
child: Container(
height: double.infinity,
child: Center(
child: Text("RowItem2"),
),
),
),
],
),
),
),
//CENTRE THE BELOW WIDGET IN MIDDLE OF SCREEN
Expanded(
child: Container(
child: GridView.builder(
shrinkWrap: true,
itemCount: 10,
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
//The maximum horizontal width of a single child Widget
maxCrossAxisExtent: 50,
// horizontal spacing between individual child widgets
mainAxisSpacing: 10.0,
//Vertical vertical spacing between individual child widgets
crossAxisSpacing: 10.0,
),
itemBuilder: (context, index) {
return Card(
child: Center(
child: Text(
index.toString(),
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold),
),
),);
},
),
),
)
],
),
),
),
);
}

Try the following, maybe your widget is taking constraints from its parents
SizedBox(
width:MediaQuery.of(context).size.width,
child:Wrap(
alignment: WrapAlignment.start
children:[
//CENTRE THE BELOW WIDGET IN MIDDLE OF SCREEN
Expanded(
child: Container(
child: GridView.builder(
shrinkWrap: true,
itemCount: 10,
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
//The maximum horizontal width of a single child Widget
maxCrossAxisExtent: 50,
// horizontal spacing between individual child widgets
mainAxisSpacing: 10.0,
//Vertical vertical spacing between individual child widgets
crossAxisSpacing: 10.0,
),
itemBuilder: (context, index) {
return Card(
child: Center(
child: Text(
index.toString(),
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold),
),
),);
},
),
),
)
],
),
),

Kindly try using a stack, As there is not pictorial representation of your expected result, I have tried according to your question statement, the code is here as follows (The colors have been changed for reference).
return Scaffold(
appBar: AppBar(
title: Text("My gridview"),
),
body: Stack(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: Container(
child: Center(
child: Text("Row Item 1"),
),
),
),
Expanded(
child: Container(
child: Center(
child: Text("RowItem2"),
),
),
),
],
),
SizedBox(
height: 30,
),
Container(
height: MediaQuery.of(context).size.height * 0.2,
padding: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.05),
child: Expanded(
child: Container(
color: Colors.amber,
child: GridView.builder(
shrinkWrap: true,
itemCount: 100,
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
//The maximum horizontal width of a single child Widget
maxCrossAxisExtent: 50,
// horizontal spacing between individual child widgets
mainAxisSpacing: 10.0,
//Vertical vertical spacing between individual child widgets
crossAxisSpacing: 10.0,
),
itemBuilder: (context, index) {
return Card(
child: Center(
child: Text(
index.toString(),
style: TextStyle(
color: Colors.red,
fontWeight: FontWeight.bold),
),
),
);
},
),
),
),
),
],
)
],
),
);

Related

How make something fixed position during scroll in Flutter

I'm up to making a screen like on the pic
I'd like to add scroll for gridview, but the trouble now is I don't really understand how to achieve that.
When I wrap Grid with SingleChildGridView, I've got an error that bottom overflowed. Example is on the second screen:
Obviously, it's happening as the GridView is a part of Column which causes the error. But how can I find a wayaround to avoid wrapping the column with let's say singlechildscrollview and at the same time making scrollable only GridView ?
Here is my code:
Scaffold(
appBar: HomeAppBar(),
bottomNavigationBar: CustomNavBar(),
backgroundColor: Colors.white,
body: Padding(
padding: const EdgeInsets.only(left: 10, right: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Hemendra',
style: Theme.of(context).textTheme.displaySmall
),
Padding(
padding: EdgeInsets.only(top: 5),
child: Text(
'Welcome to Laza.',
style: Theme.of(context).textTheme.bodyMedium
),
),
Searchbox(),
BlocBuilder<ProductBloc, ProductState>(
builder: (context, state) {
if (state is ProductLoaded) {
return Padding(
padding: const EdgeInsets.only(top: 15.0),
child: SingleChildScrollView(
child: GridView.builder(
shrinkWrap: true,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
mainAxisSpacing: 10,
crossAxisSpacing: 10,
mainAxisExtent: 300,
crossAxisCount: 2,
),
itemCount: state.products.length,
itemBuilder: (BuildContext ctx, index) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Stack(
children: [
GestureDetector(
onTap: () {
BlocProvider.of<ProductDetailsBloc>(
context)
.add(ProductDetailsEvent(
state.products[index]));
Navigator.pushNamed(
context, '/product_details');
},
child: Container(
height: 240,
child: Image.network(
state.products[index].imageUrl, fit: BoxFit.fill,),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
IconButton(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
hoverColor: Colors.transparent,
icon: Image(
image: AssetImage('heart.png'),
),
onPressed: () {},
),
],
),
],
),
Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 5),
child: Row(
children: [
Expanded(
child: Text(
maxLines: 2,
state.products[index].name,
style: Theme.of(context).textTheme.bodySmall
),
),
],
),
),
Padding(
padding: EdgeInsets.only(top: 5),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
maxLines: 2,
"\$" +
state.products[index].price
.toString(),
style: TextStyle(
color: HexColor('1D1E20'),
fontWeight: FontWeight.w600),
),
],
))
],
),
],
);
},
),
),
);
}
return Center(
child: CircularProgressIndicator(),
);
},
)
],
),
),
);
}
}
remove SingleChildScrollView and warp you BlocBuilder with Expanded widget .
so you code widget inside Scaffold body like this
Column(
children: [
searchBox(),
SizedBox(height:70, child: horizontalBrandList()),
Expanded(child: BlocBuilder(...))
],
)
created code similar UI code for better understanding update your code accordingly:
Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//SEARCH BAR
const TextField(decoration: InputDecoration(hintText: "Search")),
const SizedBox(height: 12),
// HORIZONTAL LIST VIEW
SizedBox(
height: 50,
child: ListView(
scrollDirection: Axis.horizontal,
children: List.generate(
10,
(i) => Container(
width: 50,
color: Colors.accents[i % 16],
alignment: Alignment.center,
child: Text('$i'),
),
),
),
),
const SizedBox(height: 12),
// GRID LISTVIEW
Expanded(
child: GridView.builder(
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: MediaQuery.of(context).size.width * 0.5,
childAspectRatio: 0.8,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
),
itemCount: 20,
itemBuilder: (BuildContext ctx, index) {
return Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.amber,
borderRadius: BorderRadius.circular(15)),
child: Center(child: Text(index.toString())),
);
},
),
)
],
),
)
You are adding ListView inside Column so You need to wrap with with Expanded Widget. in ListView contains own ScrollController so no need to wrap it with external SingleChildScrollView

GridView is not working inside SingleChildScrollView

I have a Column and inside that Column, I have SingleChildScrollView and inside it I have another Column. This is not working:
Column(
children: <Widget>[
SliderWidget(SliderList, "text", "text"),
const SizedBox(height: 20),
SingleChildScrollView(
child: Column(
children: [
text("Some text"),
Expanded(
child: Padding(
padding: const EdgeInsets.all(24.0),
child:
GridListing(FavouriteList, false),
),
),
],
),
),
],
),
Please suggest me alternate.
SingleChildScrollView and Expanded both are trying to get infinite height. Providing height on GridView will solve the issue.
To understand the overflow, we need to check how SingleChildScrollView is getting size and setting on children. In order to get available space, we need wrap SingleChildScrollView with Expanded widget.
Now we can wrap GridView with SizedBox(height:x
return Scaffold(
body: LayoutBuilder(
builder: (context, constraints) => Column(
children: <Widget>[
// SliderWidget(SliderList, "text", "text"),
const SizedBox(height: 20),
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
Text("Some text"),
SizedBox(
height: constraints.maxHeight * .6,
child: GridView.count(
crossAxisCount: 2,
crossAxisSpacing: 4,
mainAxisSpacing: 4,
children: List.generate(
222,
(index) => Container(
color: Colors.red,
width: 200,
height: 200,
child: Text(" $index"),
),
),
),
),
Container(
height: 500,
color: Colors.pink,
),
],
),
),
),
],
),
),
);
A better way of doing it will be using CustomScrollView
If you use the IntrinsicHeight widget around the inner column flutter can display your widget tree.
Column(
children: <Widget>[
SliderWidget(SliderList, "text", "text"),
const SizedBox(height: 20),
SingleChildScrollView(
child: IntrinsicHeight( // added widget
child: Column(
children: [
text("Some text"),
Expanded(
child: Padding(
padding: const EdgeInsets.all(24.0),
child:
GridListing(FavouriteList, false),
),
),
],
),
),
),
],
),

GridView Flutter

i'm trying to do this page
but what i get is this
this is my code
SingleChildScrollView(
child: Column(
children: [
Center(
child: Container(
margin: EdgeInsets.all(20),
width: 230,
height: 40,
child: ElevatedButton(
onPressed: () {
},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(Color(0xff28CC61)),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
),
),
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Text("Add a book", style: TextStyle(
fontSize: 20
),),
),
),
),
),
Container(
child: Text("Explore between 10 books", style: TextStyle(
fontSize: 20
),),
),
Container(
//adding: EdgeInsets.all(12),
child: SingleChildScrollView(
child: GridView.builder(
shrinkWrap: true,
physics: BouncingScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 1,
crossAxisSpacing: 20,
crossAxisCount: 2,
mainAxisSpacing: 8),
itemCount: books.length,
itemBuilder: (BuildContext ctx, index) {
return Container(
width: 50,
height: 100,
child: Card(
color: Color(0xFFEDEDED),
child: Column(
children: [
Image.asset(books[index].image, height: 150
,
width: 150,fit: BoxFit.cover,),
],
),
),
);
}),
),
),
],
),
),
ignore the colors and styles i want how to do the page
i stucked on gridview and how to write text below the picture + How can I fix my code to do it? So each image has same size as others? i tried to see the grid view documentation and i could not find anything.
Change childAspectRatio : 1 to childAspectRatio:0.7. childaspectRatio defines the ratio between width and height of children. If you set it as 1 you will get a square shaped widget. More than 1 is horizontal rectangle and less than 1 gives vertical rectangle.

How to center grid button inside red container

I want to center all grid button inside red container but it is showing big space at bottom of red container..how to solve this
Widget build(BuildContext context) {
return Center(
child: Container(
color: Colors.red,
height: MediaQuery.of(context).size.height*0.60,
width: MediaQuery.of(context).size.height*0.60,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: GridView.builder(
itemCount: 16,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4),
itemBuilder: (context,index)=>
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(child: Center(child: Text(index.toString(),)),color: Colors.blue,),
)
,),
),
),
);
}
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Colors.red,
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.height,
child: Center(
child: SizedBox(
height: MediaQuery.of(context).size.height * 0.6,
child: GridView.builder(
padding: EdgeInsets.all(16),
itemCount: 16,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4),
itemBuilder: (context, index) => Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
child: Center(
child: Text(
index.toString(),
)),
color: Colors.blue,
),
),
),
),
),
),
);
}
You can wrap the gridview.builder inside a sized box ( provided some height ) and wrap it under Center widget.
You can do it like this :
Center(
child: Container(
color: Colors.red,
height: MediaQuery.of(context).size.height * 0.60,
width: MediaQuery.of(context).size.height * 0.60,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column( // column
mainAxisAlignment: MainAxisAlignment.center, // center
children: [
Container( // if you don't have this container, there is an error
height: MediaQuery.of(context).size.height * 0.50, // new height
width: MediaQuery.of(context).size.height * 0.50, // new width
color: Colors.green,
child: GridView.builder(
padding: const EdgeInsets.all(0.0), // delete all padding from grid
itemCount: 20, // more items to scroll
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
),
itemBuilder: (context, index) => Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
child: Center(
child: Text(
index.toString(),
)),
color: Colors.blue,
),
),
),
),
],
),
),
),
)
Enclose your Grid inside a Column to allow it to be centered, because if you don't do it I can't find another way to center it because the Grid is dynamic in height and could not be centered.
And with this, you delete the big space in the red container

When scroll direction is horizontal, text overflow is not working. How can I TextOverflow.ellipsis work properly?

I would like to overflow long text in a column with Card. Text must overflow width of Card. Scroll Direction set to Axis.horizontal for that reason TextOverflow does not pass to second line or overlow. Do you have any suggestions?
SingleChildScrollView(
scrollDirection:
Axis.horizontal,
child: Row(
children: [
Column(
children: [
Flexible(
flex: 5,
child: SizedBox(
width: 80.w,
height: 80.h,
child: Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(
10.r)),
child: Center(
child: Image
.network(
productsProvider
.randomProducts[
itemIndex]
.photo,
fit: BoxFit
.cover,
),
)),
),
),
Flexible(
child: Text(
productsProvider
.randomProducts[
itemIndex]
.name,
style: TextStyle(
fontSize:
10.sp),
overflow:
TextOverflow
.ellipsis,
maxLines: 2,
),
)
],
),
],
),
);
Here is the output
This is the code that everybody can see what happens. It is not complicated but I did not find a solution to work properly.
ListView.builder(
itemCount: strings.length,
shrinkWrap: true,
controller: _scrollController,
itemBuilder: (BuildContext context, int index) {
return Column(
children: [
Padding(padding: EdgeInsets.only(bottom: 8)),
Container(
alignment: Alignment.centerLeft,
child: Text(strings[index]),
padding: EdgeInsets.only(bottom: 8, left: 8),
),
Container(
decoration: BoxDecoration(color: Colors.white),
child: Padding(
padding: EdgeInsets.all(8),
child: Column(
children: [
SizedBox(
height: 80,
width: MediaQuery.of(context).size.width,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: 2,
itemBuilder: (BuildContext context, int itemIndex) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
Column(
children: [
Flexible(
flex: 5,
child: SizedBox(
width: 80,
height: 80,
child: Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(
10)),
child: Center(
child: Image.network(
'https://ayb.akinoncdn.com/products/2019/04/24/21736/788e20d1-81ca-42da-a6bb-25c2698fafaa_size780x780_quality60_cropCenter.jpg',
fit: BoxFit.cover,
),
)),
),
),
Flexible(
child: Text(
'Osmanlı şahzade badem ezmesi. Üretimi tecrübeye sabit',
style: TextStyle(fontSize: 10),
overflow: TextOverflow.ellipsis,
maxLines: 2,
),
)
],
),
],
),
);
}),
)
],
),
),
),
],
);
});
Actually the reason behind is that you have set the scrollDirection to horizontal and inside it you are using a Row as well which also has a horizontal axis direction and after that you are passing your Text widget inside Flexible and according to Flexible widget property it will stretch it self according to it's child size. In your case Flexible has a unbounded width so it's expanding it self according to it's child which result a full length text to appear and because it's showing full content TextOverflow.ellipsis will not work.
Basically to solve this you have to wrap your Text widget to a SizedBox so that it can have a bounded width.