flutter GridView.builder won't let rest of screen scroll - flutter

I have GridView.builder middle of my screen but it does not let my screen to scroll! I must find some white space in screen in order to be able to scroll rest of my screen.
Here is how my screen structure looks like:
Widget build(BuildContext context) {
return Scaffold(
appBar: const TopBarFile(),
drawer: const DrawerFile(),
body: SafeArea(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: FutureBuilder(
future: myCards,
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// some widgets...
const SizedBox(height: 15),
// here middle of screen is GridView
SizedBox(
child: GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
),
shrinkWrap: true,
itemCount: snapshot.data['cards'].length,
itemBuilder: (BuildContext context, int index) {
return InkWell(...);
}
)
),
const SizedBox(height: 15),
// some more widgets...
]
);
} else {...}
return container();
}
),
),
),
),
),
}
Note: this grid view only has 6 items so I don't need it to be scrollable actually I just use it for design purpose but its causing scrolling issue, so I just need to be able to scroll my page even if I'm touching on top of this grid view items.
Any suggestions?

you can define a physics property with NeverScrollableScrollPhysics() value inside GridView, this will solve the issue. Always use physics property When you have nested scrollable widget.

You can give physics: NeverScrollableScrollPhysics() to GridView() or use Wrap() widget instead of GridView().

Use physics and shrinkWrap property as below:
SizedBox(
child: GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
),
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: snapshot.data['cards'].length,
itemBuilder: (BuildContext context, int index) {
return InkWell(...);
}
)
),

Related

Adding static element to gridview which is constructed by futurebuilder in flutter?

I am getting images using gridview and using futurebuilder. But I need to add one static photo.I replaced the photos from futurebuilder fine but also I want to add one photo which is static from outside of the futurebuilder.
This is how I want my gridview looks like:
I want to add this picture to gridview:
This is my code:
...
future: future,
builder: (ctx, snapshot) => snapshot.connectionState ==
ConnectionState.waiting
? Center(
child: CircularProgressIndicator(),
)
: Column(
children: [
Flexible(
flex: 5,
child: Container(
padding: EdgeInsets.only(
top: 40,
bottom: 1,
left: 40,
right: 40),
child: Consumer<Images>(
builder: (ctx, titles, ch) =>
GridView.builder(
physics: ScrollPhysics(),
itemCount: titles.items.length,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: getSize(
_currentSliderValue),
mainAxisSpacing: 50,
childAspectRatio: 115 / 162.05,
crossAxisSpacing: 5,
),
itemBuilder: (ctx, index) {
saveallimages(titles.items);
return GestureDetector(
onTap: () => add(titles
.items[index].image),
//()=>add(titles.items[index].image),
child: selected.contains(
titles.items[index]
.image.path
.toString())
? Container(
child: selectedimage(
titles
.items[
index]
.image))
: Container(
child: nonselected(
titles
.items[
index]
.image)));
}),
...
Increase itemCount by 1. In itemBuilder check if index == titles.items.length, and display your static item if so.

Container with drop shadow containing a dynamic GridView

So a design requires Containing a GridView of profiles that is dynamic in size.
The one I came up with is something like this:
class Applicants extends StatelessWidget {
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Container(
padding: EdgeInsets.all(20),
child: GridView.builder(
clipBehavior: Clip.none,
itemCount: 10,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
itemBuilder: (context, index) => _buildBox(context, index),
),
),
),
],
);
}
}
But how do I put them in a Container with a drop shadow that extends with GridView? This list is populated from DB and my attempts of placing the GridView in a Container with DropShadow always fail.
An easy way is using Card and use elevation.
Widget _buildBox(BuildContext context, int index) {
return Card(
elevation: 12,
child: Center(
child: Text("Applicant"),
),
);
}

Flutter: Scrollable Column child inside a fixed height Container

I have several containiers inside a ListView which will result in a scrollable content within a page. Each container has a Column as child and within the Column I have a title and a divider, then the actual content.
I want one of the container to be something like:
Title
--------- (divider)
Scrollable content (most likely a ListView)
What I have so far:
Container(
height: 250,
child: Column(children: <Widget>[
Text('Title'),
Divider(),
SingleChildScrollView(
child: ListView.builder(
shrinkWrap: true,
itemCount: 15,
itemBuilder: (BuildContext context, int index) {
return Text('abc');
}
)
)
]
)
The thing is that I want the container to have a specific height, but I get an overflow pixel error.
Wrap your ListView with Expanded. Remove your SingleChildScrollView as ListView has its own scrolling behaviour. Try as follows:
Container(
height: 250,
child: Column(children: <Widget>[
Text('Title'),
Divider(),
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: 15,
itemBuilder: (BuildContext context, int index) {
return Text('abc');
}
),
)
]
))
Wrap your ListView.builder() widget inside a SizedBox() widget and specify available height after accommodating Title() widget.
Container(
height: 250,
child: Column(children: <Widget>[
Text('Title'),
Divider(),
SizedBox(
height: 200, // (250 - 50) where 50 units for other widgets
child: SingleChildScrollView(
child: ListView.builder(
shrinkWrap: true,
itemCount: 15,
itemBuilder: (BuildContext context, int index) {
return Text('abc');
}
)
)
)
]
)
You can also use Container() widget instead SizedBox() widget but only if needed.
SizedBox() is a const constructor where Container() widget is not, so SizedBox() allows the compiler to create more efficient code.

Issues with GridView for the following UI

I am trying to construct the following UI, but having issues with that. More specifically I tried different ways of doing this with GridView, but had no luck since I was not able to switch from 2 to 1 for crossAxisCount, because after showing the favorite cakes I need to "come back" to "normal" and show one block on one line for "Similar Products". Here is what I tried:
body: new LayoutBuilder(
builder: (context, constraint) {
return Padding(
padding: const EdgeInsets.fromLTRB(8.0, 0, 8.0, 0),
child: new GridView(
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: constraint.maxWidth / constraint.maxHeight,
),
children: <Widget>[
// those widgets here will be created dynamically at the end
// manually created a few just for illustration
new MyFavoriteWidget(),
new MyFavoriteWidget(),
new MyFavoriteWidget(),
new MyFavoriteWidget(),
new MyFavoriteWidget(),
new MyFavoriteWidget(),
new MyFavoriteWidget(),
new MyFavoriteWidget(),
new Container(
child: Text("Similar Products"),
),
// same for those widgets
new SimilarProductWidget(),
new SimilarProductWidget(),
new SimilarProductWidget(),
new SimilarProductWidget(),
],
),
);
},
),
But this renders just 2 columns, which is what I want for the top part, but after the list of MyFavoriteWidget() I need to switch to normal layout and have one block on one line. And if I take this part out of the GridView it won't be visible. I feel like GridView is still the best way of implementing this but was not able to find a way around it. Even a skeleton code to get started or a hint how to overcome this issue will be much helpful.
I offer you try this code. For top list use GridView.count and for bottom list use ListView.builder. I give you a simple example to understand it. Run code below and see the result.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Your heading'),
),
body: SafeArea(
child: ListView(
shrinkWrap: true,
physics: ScrollPhysics(),
children: [
GridView.count(
crossAxisCount: 2,
scrollDirection: Axis.vertical,
physics: ScrollPhysics(),
shrinkWrap: true,
children: List.generate(
6,
(index) => Container(
margin: EdgeInsets.all(10),
width: 50,
height: 50,
color: Colors.yellow,
),
),
),
ListView.builder(
physics: ScrollPhysics(),
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: 10,
itemBuilder: (BuildContext context, int index) {
return Card(
color: Colors.red,
child: Container(
height: 70,
margin: EdgeInsets.all(30),
width: double.infinity,
),
);
},
),
],
)));
}

All children of this widget must have a key(edit:)

enter image description hereI am trying to make a ReorderableListView, which needs a key. I put it, however it returns the error "All children of this widget must have a key". Can anyone help me? (I've seen similar problems here but I still couldn't solve it)
ReorderableListView(
onReorder: _onReorder,
scrollDirection: Axis.vertical,
padding: const EdgeInsets.symmetric(vertical: 8),
children: <Widget>[
ListView.builder(
itemCount: dias.length,
itemBuilder: (context, int index) {
return Padding(
key: ValueKey(dias[index]),
padding: EdgeInsets.all(0),
child: _cartaodia(context, index),
);
}
),
],
)
edit: I saw some examples that used the key of this form, however the index it does not recognize the index as shown in the image
Your listViewBuilder also require Key.
ListView.builder(
key: Key(dias.length.toString()), // added line
itemCount: dias.length,
Update:
ConstrainedBox(// added widget
constraints:
BoxConstraints(maxHeight: MediaQuery.of(context).size.height),
key: Key("Const"),
child: ListView.builder(
// add the value key inside the list view instead
key: ValueKey("list"),
itemCount: 50,
// shrinkWrap: true,
itemBuilder: (context, int index) {
return Padding(
padding: EdgeInsets.all(0),
child: Text("hello"),
);
}),
),
Try adding the ValueKey inside the ListView.builder widget instead.
Like this:
ReorderableListView(
onReorder: _onReorder,
scrollDirection: Axis.vertical,
padding: const EdgeInsets.symmetric(vertical: 8),
children: <Widget>[
ListView.builder(
// add the value key inside the list view instead
key: ValueKey(dias[index]),
itemCount: dias.length,
itemBuilder: (context, int index) {
return Padding(
padding: EdgeInsets.all(0),
child: _cartaodia(context, index),
);
}
),
],
)