Controlling `GridView.builder` scroll behavior in Flutter - flutter

How can I customize or control GridView.builder scroll behavior such that it doesn't bounce back up to the top of the grid once the end of the grid is reached? I've tried changing physics but that doesn't seem to work for GridView. I've also tried to add a constant scroll behavior using ClampingScrollPhysics instead of BouncingScrollPhysics but this simply renders the grid unscrollable.
The bounce back is so bad that it doesn't allow the user to click on the last row of grid items. I tried to wrap the gridview in a container with padding but this also does not work. Any ideas?
return GridView.builder(
padding: const EdgeInsets.all(10.0),
// // physics: ClampingScrollPhysics(),
itemCount: loadedGroups.length,
itemBuilder: (ctx, i) => ChangeNotifierProvider.value(
value: loadedGroups[i],
child: CardWidget(
id: loadedGroups[i].groupId as String,
cardLabel: loadedGroups[i].title,
imgPath: loadedGroups[i].imageUrl as String,
labelColor: Color.fromRGBO(0, 0, 0, .70),
)),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 2 / 2,
crossAxisSpacing: 10,
mainAxisSpacing: 25,
mainAxisExtent: 190,
));
}

Related

Flutter: Using SliverChildBuilderDelegate in a GridView.custom, Get Widget Constraints for Draggable

I am attempting to create a custom grid view, and i need to put constraints on the Draggable feedback or it expands to cover the entire screen. Normally in builders, there is a constraints variable passed, but there is not one in the SliverChildBuilderDelegate. What would be the best way to limit the size of the feedback of the draggable to the current size of the widget? The ?'s in feedback is where the variable should go.
return GridView.custom(
shrinkWrap: true,
primary: false,
scrollDirection: Axis.vertical,
controller: _scrollController,
physics: const ClampingScrollPhysics(),
gridDelegate: SliverQuiltedGridDelegate(
crossAxisCount: 4,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
repeatPattern: QuiltedGridRepeatPattern.inverted,
pattern: widget.pattern,
),
childrenDelegate: SliverChildBuilderDelegate(
childCount: widget.children.length,
(context, index) {
var selectedWidget = widget.children[index];
return LongPressDraggable<GlobalKey>(
data: selectedWidget.key,
onDragStarted: _onDragStarted,
onDragEnd: _onDragEnd,
feedback:
SizedBox(width: ?, height:?, child: selectedWidget),
childWhenDragging: Container(),
child: selectedWidget,
)}))

Flutter GridView off screen widgets destroyed on scroll

I have a screen with a GridView widget containing custom Cards with images and texts. When the app initially launches it loads all the cards and their images, however, they get destroyed when scrolled off the screen. Is there a way that I can stop flutter from destroying the off-screen widgets?
Expanded(
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1.5,
),
itemCount: categories.length,
itemBuilder: (context, index) => CategoryCard(
category: categories[index],
),
),
),
Give flex or shrinkWrap: true, or use both
Expanded(
flex: 3, <--
child: GridView.builder(
shrinkWrap: true, <--
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1.5,
),
itemCount: categories.length,
itemBuilder: (context, index) => CategoryCard(
category: categories[index],
),
),
),
Figured it out! GridView, ListView, etc., have addAutomaticKeepAlives and cacheExtent properties. By default addAutomaticKeepAlives: true doesn't destroy off-screen widgets, and providing the cacheExtent: DOUBLE VALUE describes how many pixels the cache area extends before the leading edge and after the trailing edge of the viewport.

Why gridview reload images in Flutter?

I'm trying to use show images using by Image.file(File(path)) in gridview. When I scrolling it down and then up it's reloading images. This caused showing them in white. When I'm looking for this issue there is mentions "lazy loading list" but I don't think it's related with this. Also I tried caching Image widget with LruCache but it's still same. How can I prevent this reloading?
Here is my code snippet:
child: GridView.builder(
itemCount: paths.length,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 0.5,
crossAxisSpacing: 6,
mainAxisSpacing: 6,
crossAxisCount: 5,
),
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onTap: () => {remove(paths[index])},
child: Image.file(File(paths[index])),
);
},
),
This is an error: stop reason = EXC_RESOURCE RESOURCE_TYPE_MEMORY flutter
GridView(gridDelegate: gridDelegate, cacheExtent: 9999,)

Flutter web scrollview with mouse outside of listview

I have a GridView that I want to make scrollable even when the mouse is outside of the GridView. I have tried to add the GridView inside a SingleChildScrollView and added shrinkWrap: true to the GridView. I have also tried adding a Column around the GridView and Expanded as well. Here is the code:
return SingleChildScrollView(
child: Column(
children: [
Container(
constraints: BoxConstraints(maxWidth: 750),
child: GridView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
padding:
EdgeInsets.symmetric(horizontal: 30, vertical: 10),
itemCount: course.subjects.length,
itemBuilder: (context, idx) {
return CourseSubjectListEl(course, idx, data);
},
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisSpacing: 10,
childAspectRatio: 0.7,
mainAxisSpacing: 0,
crossAxisCount: 2),
),
),
],
),
);
As you can see on the screenshot, you can only scroll when the mouse is over the GridView. I think this problem can cause confusion for web users, where you normally can scroll with the mouse everywhere.
You can add
primary: false,
Property inside GridView. That will make the GridView scroll physics false and will act on how the parent scrolls (which in case is your SingleChildScrollView).
Probably you might want to remove physics: NeverScrollableScrollPhysics(), and add the above property.
Note: Make sure your scrollview contains the whole width of the screen you want to scroll

how to render gridviewbuilder's last element in the middle

i am using gridview.builder to list these icons with crossaxiscount of 3 i want to display the icons of 2nd row in the middle(add spacing before tv icon so both icon shift to the middle)
GridView.builder(
itemCount: state.productList.length,
shrinkWrap: true,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 5,
childAspectRatio: 2),
itemBuilder: (context, i) {
return Container(
child: FlatButton(
child: Image.asset(_icons[i]),
onPressed: () {
_productListBloc.add(
ItemTapProductListEvent(
state.productList[i]));
},
),
);
}),
use flutter_staggered_grid_view for customised grid layout.