Can't scroll ListView when child expands height - flutter

I have a ListView.builder that renders a list of Containers who can expand in height when the user clicks on it ( I'm using AnimatedSize to wrap the Containers), however I noticed that when the Container is expanded I can't scroll the ListView by pressing and dragging around the expanded area, only in the area that Container occupied originally.
ListView.builder(
physics: AlwaysScrollableScrollPhysics(),
itemCount: profilesList.profilesCount,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
return ProfileBar(
id: profilesList.profiles[index].id!,
index: index,
name: profilesList.profiles[index].name,
emoji: profilesList.profiles[index].emoji,
gender: profilesList.profiles[index].gender,
color: profilesList.profiles[index].color,
height: profilesList.profiles[index].height,
birthday: profilesList.profiles[index].birthday,
isSelected: profilesList.selectedProfileID ==
profilesList.profiles[index].id,
onSelect: (_) async {
profilesList.selectProfile(
profilesList.profiles[index].id!);
Provider.of<GoalModel>(context, listen: false).getGoal(profilesList.profiles[index].id!);
await UserSettings.setProfile(
profilesList.profiles[index].id!);
_getRecords(context);
});
},
),
Is there a way to fix this?

Wrap that Listview with SingleChildScrollView and add physics : NeverScrollableScrollPhysics() to Listview and check.

So I found my problem is that my list item had a GridView widget, I changed the physics to NeverScroll and fixed it.

Related

How ListView can Stop at each element in Flutter

My question is very simple but I did not find a result.
In a ListView.builder (with horizontal scroll) for example if there are 5 elements the user can scroll them all at once. I would like that the user can scroll only 1 by 1.
In short I would like the animation of the list to stop at each element.
Example of my list :
Widget _list()
{
return ListView.builder(
physics: const ClampingScrollPhysics(),
scrollDirection: _horizontalDisplay? Axis.horizontal : Axis.vertical,
itemCount: data!.length,
itemBuilder: (context, index)
{
return widgetToDisplay(index);
}
);
}
The ListView.builder can't make it, you need to use carousel_slider package

How to make a staggered grid view with varying image height in flutter?

I wanted to have a staggered grid view with Card widgets, I want the height of the card to be dependent of the height of the image being loaded.
Since my build method is too long, here is my code for my card view in gist:
https://gist.github.com/brendoncheung/2026a64410eddde20fa8ec740bbb9d84
The SizedBox on line 7 is what I believe is making the card to have a constant height, but if I remove the SizedBox it crashes.
If I remove the SizedBox, then I will get this error:
RenderFlex children have non-zero flex but incoming height constraints
are unbounded.
I have made sure that the parents of all the Column and Row widget doesn't have a unbound constraint.
Here is my StaggeredGridView code:
#override
Widget build(BuildContext context) {
return StaggeredGridView.countBuilder(
crossAxisCount: 2,
itemCount: items.length,
itemBuilder: (context, index) => ItemWidget(
item: items[index],
onTap: (item) => Navigator.of(context).push(MaterialPageRoute(
builder: (context) => DetailItemScreen(
item: item,
)))),
staggeredTileBuilder: (index) => StaggeredTile.fit(1),
);
}
This 2 images below is the card widget, and the other one is with the debug paint on,
With comparison of my StaggeredGridView settings with yours only thing that's different, is mine has this two settings which help fix viewport issue.
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
But I agree sized box is probably making height of same size.

Cant scroll with ListView.builder()

I was wondering if anyone had an issue where they use a ListView.builder() and then it doesn't want to scroll
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: widget.product.category.length,
itemBuilder: (context, index) {
final item = widget.product.category[index];
return ListTile(title: Text(item));
},
)
I'd suggest you do the following:
Remove shrinkWrap and make sure the value passed to itemCount is large enough to make the widget scroll.
If you place the list view inside a vertically scrolling list, it's not going to scroll... In this case, you should probably be using slivers

I need to make a non-scrollable Gridview with itemBuilder

I want to create a grid view inside a listview. It is now being nested and not working well. I want to make it GridView because I want itemBuilder to view the list in Map with index.
Like this
return GridView.builder(
shrinkWrap: false,
primary: false,
itemCount: kadakkalproducts.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemBuilder: (BuildContext context, int index) {
return SingleProdc(
product_name: kadakkalproducts[index]['name'],
product_picture: kadakkalproducts[index]['picture'],
product_price: kadakkalproducts[index]['price'],
product_image1: kadakkalproducts[index]['image1'],
product_image2: kadakkalproducts[index]['image2'],
product_des: kadakkalproducts[index]['des'],
product_det: kadakkalproducts[index]['det'],
);
},
);
I have used shrinkwrap and primary to stop nested loop. But it doesn't work.
Please help me out to stop scrolling in GridView
Add this line inside your GridView
physics:NeverScrollableScrollPhysics()
https://api.flutter.dev/flutter/widgets/ScrollPhysics-class.html

Refresh indicator doesn't work when list doesn't fill the whole page

I have a page the has a list with refresh indicator. When I have many elements in the list (filling the whole view and more, i.e. I can scroll), the refresh indicator works.
However, when I have only one or two elements in the list (nothing to scroll), then the refresh indicator doesn't work. Is this the expected behaviour? Is there a way to get the indicator to work also for short lists?
I tried wrapping the list view (child of refresh indicator) with a scroll bar but the problem still persists.
Future<void> _onRefresh() async {
_getPeople();
}
#override
Widget build(BuildContext context) {
super.build(context);
return new Container(
child: _items.length == 0
? Center(child: CircularProgressIndicator())
: new RefreshIndicator(
onRefresh: _onRefresh,
child: Scrollbar(
child: new ListView.builder(
controller: controller,
itemBuilder: (context, index) {
return PeopleCard(
People: _items[index],
source: 2,
);
},
itemCount: _items.length,
),
)),
);
}
If the length of the items list is 1 or 2 or any amount that doesn't need scrolling, refresh indicator should also work.
Set the physics to AlwaysScrollableScrollPhysics just like the below code.
new RefreshIndicator(
key: _refreshIndicatorKey,
color: Colors.blue,
onRefresh: (){
setState(() {
_future = fetchPosts(http.Client());
_getAvalailableSlots();
});
},
child: ListView.builder(
physics: AlwaysScrollableScrollPhysics(),
itemCount: data.length,
itemBuilder: (context, i) {
//do something
}
)
)
Case 1:
Use AlwaysScrollableScrollPhysics() in your Listview or SingleChildScrollView.
physics: const AlwaysScrollableScrollPhysics(),
Case 2:
If you want to use other scroll physics, use this way...
physics: BouncingScrollPhysics(
parent: AlwaysScrollableScrollPhysics(),
),
Case 3:
Make sure you didn't make shrinkWrap, true. ShrinkWrap has to be false like default.
shrinkWrap: true. ❌
shrinkWrap: false. ✅
shrinkWrap: false,
Case 4:
If you have any custom widgets other than a listview, use stack and listview this way...
RefreshIndicator(
onRefresh: () async {
print('refreshing');
},
Stack(
children: [
YourWidget(),
ListView(
physics: const AlwaysScrollableScrollPhysics(),
),
],
),
),
To use with BouncingScrollPhysics:
RefreshIndicator(
onRefresh: () async {
},
child: ListView.builder(
physics: BouncingScrollPhysics(
parent: AlwaysScrollableScrollPhysics()),
itemBuilder: (context, index) {
return Text("${index}");
}),
To make RefreshIndicator always appear, set physics: const AlwaysScrollableScrollPhysics() for the scrollable child like below.
ListView(
physics: const AlwaysScrollableScrollPhysics(),
children: <Widget>[widget.bodyWidget]
)
If you still have some errors, the below might help.
ListView widget needs to have height value to be "always" scrollable vertically. So wrap it with SizedBox or some other proper widget and set the height.
How to fix the height? Get the height of viewport using MediaQuery.of(context).size.height and, if needed, subtract the value of non-scrollable part.
If you use SingleChildScrollView and it's not working with AlwaysScrollableScrollPhysics(), it is because the child doesn't have height. fix the child's height or just use ListView.
To sum up, the following worked for me.
sizes.bottomNavigationBar and sizes.appBar are the constant variables I made to customize the appbar and navbar.
RefreshIndicator(
onRefresh: widget.onRefresh,
child: SizedBox(
height: MediaQuery.of(context).size.height -
sizes.bottomNavigationBar -
sizes.appBar,
child: ListView(
physics: const AlwaysScrollableScrollPhysics(),
children: <Widget>[widget.bodyWidget]
)),
)
If you're finding any reliability, Refresh indicator does not show up part of the official doc would help.
If you're using ListView inside of Column with Expanded.
Try Removing
shrinkWrap:true