Flutter how to remove gridview top space - flutter

I am getting a space on top of my gridview. I have tried to remove it without success.
It looks like this:
What I want:
Here is my code:
Container(
margin: EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Check",
style: TextStyle(color: Colors.black, fontSize: 18, fontWeight: FontWeight.bold),
textAlign: TextAlign.left,
),
GridView.count(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
crossAxisCount: 1,
crossAxisSpacing: 2,
mainAxisSpacing: 10,
childAspectRatio: 5.1,
children: <Widget>[
GestureDetector(
child: _buildWidget("Car", 0),
onTap: () => setState(() => _languageIndex = 0),
),
GestureDetector(
child: _buildWidget("Boat", 1),
onTap: () => setState(() => _languageIndex = 1),
),
],
),
],
));
Widget _buildWidget(String language, int index) {
bool isSelected = _languageIndex == index;
return Container(
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
border: Border.all(color: isSelected ? Colors.blue.withOpacity(1.0) : Colors.black26),
color: isSelected ? Colors.white.withOpacity(0.0) : Colors.white
),
child:
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(width:10),
Text(
language,
style: TextStyle(fontSize: 16,fontWeight: FontWeight.bold, color: isSelected ? Colors.black : Colors.black26),
),
SizedBox(width:20),
],)
);
}
What can I do to remove the space between the text and the gridview? Or can I do it in another way to get the output I am looking for?

The GridView widget has a default padding, you can remove the padding by giving it a padding of EgdeInsets.zero.
GridView.count(
padding: EdgeInsets.zero // set padding to zero
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
crossAxisCount: 1,
crossAxisSpacing: 2,
mainAxisSpacing: 10,
childAspectRatio: 5.1,
children: <Widget>[
GestureDetector(
child: _buildWidget("Car", 0),
onTap: () => setState(() => _languageIndex = 0),
),
GestureDetector(
child: _buildWidget("Boat", 1),
onTap: () => setState(() => _languageIndex = 1),
),
],
),

Related

GridView infinite scrolling CircularProgressIndicator position

In my gridView there is a condition when to show CircularProgressIndicator(), but it is displayed incorrectly, in the gridView element, I need it to be displayed below the gridView. How can I show CircularProgressIndicator() correctly?
Widget buildCatalog(List<Product> product) => GridView.builder(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
// mainAxisExtent: ,
maxCrossAxisExtent: 300,
childAspectRatio: MediaQuery.of(context).size.width*1.22 /
(MediaQuery.of(context).size.height),
crossAxisSpacing: 10,
mainAxisSpacing: 10),
controller: sController,
itemCount: product.length + 1,
itemBuilder: (context, index) {
if (index < product.length) {
final media = product[index].media?.map((e) => e.toJson()).toList();
final photo = media?[0]['links']['local']['thumbnails']['350'];
final productItem = product[index];
return GestureDetector(
onTap: () {
},
child: Container(
child: Column(
children: <Widget>[
InkWell(
child: Container(
margin: EdgeInsets.only(top: 5),
child: Image.network(...)
),
),
),
SizedBox(
height: 10,
),
Text(
'${productItem.name}\n',
textAlign: TextAlign.center,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 14),
),
// Spacer(),
SizedBox(height: 8),
Text('${productItem.price} ₸',
textAlign: TextAlign.start,
style: TextStyle(fontSize: 20, color: Colors.red)),
SizedBox(height: 5),
buildButton(index, productItem.id),
],
),
),
);
}
return const Center(child: CircularProgressIndicator(),);
},
);
wrap Gridview() and CircularProgressIndicator() into a column,
and change shrinkWarp and physics like below
Column(
children: [
Gridview.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: product.length + 1,
itemBuilder: (context, index) {
//return something you want
},
),
const CircularProgressIndicator()
],
)

GridView infinite pagination Range error Invalid value: Not in inclusive range 0..21: 22

I have infinite pagination in my gridView but when i want to add CircularProgressIndicator() to my GridView i get RangeError (index): Invalid value: Not in inclusive range 0..21: 22, in itemCount i have items + 1, why is my CircularProgressIndicator() not working?
Widget buildCatalog(List<Product> product) => GridView.builder(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
// mainAxisExtent: ,
maxCrossAxisExtent: 300,
childAspectRatio: MediaQuery.of(context).size.width*1.22 /
(MediaQuery.of(context).size.height),
crossAxisSpacing: 10,
mainAxisSpacing: 10),
controller: sController,
itemCount: product.length + 1,
itemBuilder: (context, index) {
final media = product[index].media?.map((e) => e.toJson()).toList();
final photo = media?[0]['links']['local']['thumbnails']['350'];
if (index < product.length) {
final productItem = product[index];
return GestureDetector(
onTap: () {
},
child: Container(
child: Column(
children: <Widget>[
InkWell(
child: Container(
margin: EdgeInsets.only(top: 5),
child: Image.network(...)
),
),
),
SizedBox(
height: 10,
),
Text(
'${productItem.name}\n',
textAlign: TextAlign.center,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 14),
),
// Spacer(),
SizedBox(height: 8),
Text('${productItem.price} ₸',
textAlign: TextAlign.start,
style: TextStyle(fontSize: 20, color: Colors.red)),
SizedBox(height: 5),
buildButton(index, productItem.id),
],
),
),
);
}
return const Center(child: CircularProgressIndicator(),);
},
);

Flutter: Make all screen scrollable with GridView.builder inside

In my home screen my app shows carousel first then a vertical list of challenges cards retrieved from Cloud Firestore using GridView.builder as follows:
GridView.builder(
scrollDirection: Axis.vertical,
itemCount: _challenges.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 4),
),
itemBuilder: (context, index) {
return InkWell(
onTap: () {
if (_challenges[index]["isLocked"] == "true") {
showLockedDialog();
} else {
checkParticipation(index);
if (checkPart == true) {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) =>
ChallengeDetails(_challenges[index])));
}
checkPart = true;
}
},
child: Stack(
children: [
Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(15),
child: Image(
image: NetworkImage(_challenges[index]["image-path"]),
fit: BoxFit.cover,
height: 150,
width: 350,
opacity: _challenges[index]["isLocked"] == "true"
? AlwaysStoppedAnimation(.4)
: null,
),
),
),
Center(
child: Text(
"${_challenges[index]["name"]}\n",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
),
),
Center(
child: Text(
"\n${_challenges[index]["date"]}",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
textDirection: TextDirection.ltr,
)),
Center(
child: SizedBox(
height: 130,
width: 130,
child: _challenges[index]["isLocked"] == "true"
? Image.asset("assets/lock-icon.jpg")
: null,
),
)
],
),
);
});
Everything retrieving fine and it is rendered in my home_screen as follows:
body: Column(
children: [
AdsBanner(),
SizedBox(
height: 30,
),
Padding(
padding: const EdgeInsets.only(right: 8, left: 8, bottom: 5),
child: Row(
children: [
Text(
AppLocalizations.of(context)!.challenges + " ",
style: TextStyle(fontSize: 20),
),
Text(
AppLocalizations.of(context)!.clickToParticipate,
style: TextStyle(fontSize: 15),
)
],
),
),
Expanded(child: ChallengeCard()),
],
),
The problem is that only the GridView area is scrolling and what am seeking for is to scroll the whole screen with the GridView area, I was trying to use the CustomScrollView() but its not working properly.
I'll be thankful for any help.
First in your GridView.builder add these:
GridView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
...
)
then in your home_screen wrap your column with SingleChildScrollView:
SingleChildScrollView(
child: Column(
children: [
AdsBanner(),
SizedBox(
height: 30,
),
Padding(
...
),
),
You can provide physics: NeverScrollableScrollPhysics() on GridView to disable scroll effect. If you want scrollable as secondary widget use primary: false, to have Full Page scrollable, you can use body:SingleChildScrollView(..) or better using body:CustomScrollView(..)

How to fix "Could not find the correct Provider<Product> above this ProductItem Widget "?

I am very much new to flutter. This is my first time using providers. I have been through every solution out there but nothing seems to help.
In a shopping app I am developing, I tried to use the provider package to pass data to my widget dynamically.
I am sharing the code and the screenshot of the very big error message. Hope somebody could help
Gridview builder
final productData = Provider.of<ProductsProvider>(context);
final products = productData.items;
return GridView.builder(
padding: EdgeInsets.all(10),
itemCount: products.length,
itemBuilder: (context, index) => ChangeNotifierProvider.value(
value: products[index], child: ProductItem()),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 0.75,
crossAxisSpacing: 10,
mainAxisSpacing: 10),
);
Individual product item in the grid
final product = Provider.of<Product>(context);
return Container(
child: GestureDetector(
onTap: () {
Navigator.of(context)
.pushNamed(ProductDetails.routeName, arguments: product.id);
},
child: Card(
color: Colors.white,
elevation: 6,
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
//product image
Image(image: AssetImage(product.imageUrl)),
Padding(
padding: EdgeInsets.symmetric(vertical: 0, horizontal: 10),
//item name and fav button
child: Flex(
direction: Axis.horizontal,
children: <Widget>[
Expanded(
child: Text(
product.name,
style: Theme.of(context)
.textTheme
.headline1
.copyWith(fontSize: 16, color: Colors.black),
)),
IconButton(
icon: Icon(
product.isFav
? Icons.favorite
: Icons.favorite_border,
color: Colors.red,
),
onPressed: () {
product.toggleFav();
})
],
),
),
// price and buy button
Padding(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
child: Flex(
direction: Axis.horizontal,
children: <Widget>[
Expanded(
child: Text(
"\$ " + product.price.toString(),
style: Theme.of(context).textTheme.headline1.copyWith(
color: Theme.of(context).primaryColor, fontSize: 15),
)),
SizedBox(
width: 60,
child: RaisedButton(
onPressed: () {},
color: Colors.orange,
child: Text(
"Buy",
style: TextStyle(fontFamily: 'Prompt', fontSize: 14),
),
),
)
],
),
),
],
),
),
),
);
screenshot of error
You need to declare the provider in you main material widget. Atm you are using it but you haven't told flutter that you will use it.
https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple#changenotifierprovider

Flutter/Dart: Create a GridView where the first item is a unique grid item

I am new to Flutter and Dart but I have a grid view on one of my screens and I want the first grid item to be a unique button that allows the user to add a student. You can see in the image below an example of what I am trying to accomplish. How do I create a unique view with the first item allowing a user to add a student?
Grid Class:
body: Padding(
padding: const EdgeInsets.only(left: 15.0, right: 15.0),
child: Column(
children: <Widget>[
ProfileHeader(),
ProfileViewSwitch(),
ProfileSearch(),
Flexible(
//Below is the GridView used for each student in the class
child: GridView(
//TODO convert to a builder for performance efficiency
padding: const EdgeInsets.only(top: 10.0),
children: DUMMY_CATEGORIES
.map(
(catData) => ImageItem(
catData.firstName,
catData.lastName,
catData.color,
catData.initials,
),
)
.toList(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
//maxCrossAxisExtent: 150,
crossAxisCount: 3,
childAspectRatio: 1,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
),
),
],
),
),
Image Item Class:
Widget build(BuildContext context) {
return InkWell(
onTap: () => selectCategory(context),
borderRadius: BorderRadius.circular(15),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
child: new Column(
children: <Widget>[
ClipOval(
child: Material(
color: color, // button color
child: InkWell(
//splashColor: Colors.red, // inkwell color
child: SizedBox(
width: 80,
height: 80,
child: Align(
alignment: Alignment.center,
child: Text(initials,
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 35)),
),
),
),
),
)
],
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
//crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
child: new Column(
children: <Widget>[
new Text(
firstName,
textAlign: TextAlign.center,
style:
TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
),
new Text(
lastName,
textAlign: TextAlign.center,
style:
TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
),
],
),
),
],
),
],
),
);
}
}
You can achieve the desired result in two ways,
Method 1: Using GridView,builder, return your Button at index 0 - I'd recommend to using this method.
GridView.builder(
//TODO convert to a builder for performance efficiency
padding: const EdgeInsets.only(top: 10.0),
itemCount: DUMMY_CATEGORIES.length + 1,
itemBuilder: (context, i) {
if (i == 0) {
return IconButton(
icon: Icon(Icons.add),
onPressed: () {},
);
}
final catData = DUMMY_CATEGORIES[i - 1];
return ImageItem(
catData.firstName,
catData.lastName,
catData.color,
catData.initials,
);
},
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
//maxCrossAxisExtent: 150,
crossAxisCount: 3,
childAspectRatio: 1,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
)
Method 2: Concat a null or unique value in from and handle during map
GridView(
//TODO convert to a builder for performance efficiency
padding: const EdgeInsets.only(top: 10.0),
children: [null, ...DUMMY_CATEGORIES].map(
(catData) {
if (catData == null) {
return IconButton(
icon: Icon(Icons.add),
onPressed: () {},
);
}
return ImageItem(
catData.firstName,
catData.lastName,
catData.color,
catData.initials,
);
},
).toList(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
//maxCrossAxisExtent: 150,
crossAxisCount: 3,
childAspectRatio: 1,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
)
Hope that helps!