when I try to add a list view builder, my entire screen goes black
here is the list view builder code
ListView.builder(
shrinkWrap = true,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
final data = courseCardList[index];
return Row(
children: [
CourseList(
color: data.color,
icon: data.icon,
caption: data.caption,
head: data.head,
timePeriod: data.timePeriod,
rating: data.rating,
),
],
);
},
),
when I build the UI, that shows a blank screen, what mistake am I making here?
Horizontal Listview.builder needs a fixed height. Horizontal list item shouldn't have a endless height. so solution came to my mind just wrap Listview.builder with a conatiner and set height of that container like below.
The Flutter framework can only know the height of a widget once it's been built.
If you're building ListView children dynamically, it can't calculate the required height of the ListView until all it's children have been built, which might never happen (infinite ListView).
You can either give the ListView a fixed height and build its children dynamically or have the ListView's height depend on it's children.
Container(
height: 200,
child: ListView.builder(
shrinkWrap = true,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
final data = courseCardList[index];
return Row(
children: [
CourseList(
color: data.color,
icon: data.icon,
caption: data.caption,
head: data.head,
timePeriod: data.timePeriod,
rating: data.rating,
),
],
);
},
),
);
Under ListView Widget
use shrinkWrap: true
add itemCount, itemCount: courseCardList.length
If it still doesn't solve the issue,
Remove the Row() widget as I can see you are only returning a single widget under it, so directly return that widget CourseList()
The code should look something like this.
ListView.builder(
shrinkWrap : true,
itemCount: courseCardList.length,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
final data = courseCardList[index];
return CourseList(
color: data.color,
icon: data.icon,
caption: data.caption,
head: data.head,
timePeriod: data.timePeriod,
rating: data.rating,
);
},
),
I think you forgot the itemCount
Expanded(
child:ListView.builder(
shrinkWrap = true,
itemCount = 5,// add this line or put courseCardList.length
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
final data = courseCardList[index];
return Row(
children: [
CourseList(
color: data.color,
icon: data.icon,
caption: data.caption,
head: data.head,
timePeriod: data.timePeriod,
rating: data.rating,
),
],
);
},
),
),
Refer ListView and Long List
provide itemCount to your ListviewBuilder and also wrap it with Expanded or some fixed size widget like container like:
Expanded(
child: ListView.builder(
itemCount: your counts(int)
.....
.....
)
)
Related
I used SingleChildScrollView in the table I created friends. I want SingleChildScrollView to stay on the screen all the time, how can I do this (i.e. I don't want it to be shown only when I come with the mouse)
my code
enter link description here
I want the scrollbar to stay fixed
wrap your List with ScrollBar.
set isAlwaysShown = true
Scrollbar(
isAlwaysShown: true,
child: GridView.builder(
itemCount: 10,
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
itemBuilder: (BuildContext context, int index) {
return Center(
child: Text('item $index'),
);
},
),
);
So basically I ListView.builder widget inside of a fixed container.
Container(
height: 500,
child: TabBarView(
children: [
Container(
height: 500,
color: Colors.red,
child: ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: 100,
itemBuilder: (context, index) {
return Center(child: Text("This is index $index"));
},
),
),
Center(child: Text("Second Tab")),
Center(child: Text("Third Tab")),
],
),
),
Issue:
The issue with this widget is that since it is inside a container of a fixed height, the content of the list is cut off. I want the list to scroll along with the rest of the page so I don't want to remove the shrinkWrap nor NeverScrollableScrollPhysics(). I want it so that the list takes up as much room as it needs.
Things I've tried:
Wrap the ListView with a Column: this causes the widget to overflow and when I add the SingleChildScrollView around that Column, it removes the functionality of the shrinkWrap and NeverScrollableScrollPhysics().
Checked this answer. The parent widget is actually a CustomScrollView and this widget is inside of a SliverToBoxAdapter. That's why the container has a fixed size in the first place.
What can I do to get the ListView to take up as much room as it want? Thank you!
Wrap your container with SingleChildScrollView and make scrollPhysics
SingleChildScrollView(
Container(
height: 500,
color: Colors.red,
child: ListView.builder(
shrinkWrap: true,
physics: ScrollPhysics(),
itemCount: 100,
itemBuilder: (context, index) {
return Center(child: Text("This is index $index"));
},
),
),
)
I have the following source code:
#override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
controller: scrollController,
slivers: <Widget>[
SliverList(
delegate: SliverChildBuilderDelegate(
(context, cardIndex) {
return Container(
color: Colors.white,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Main Course',
style: kRestaurantMenuTypeStyle,
),
ListView.builder(
itemCount: menuCards[cardIndex].menuItems.length,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
itemBuilder: (context, itemIndex) {
return RestaurantMenuItem(
menuItem: menuCards[cardIndex].menuItems[itemIndex],
);
},
),
],
),
);
},
childCount: menuCards.length,
),
),
],
),
);
}
Unfortunately, the ListView.builder() creates this extra space on top automatically. This is shown in the image below. That is the big white space between the 'Main Course' and 'Pancit Malabon' texts.
I don't understand why ListView does that. How do I remove the space?
To avoid this behaviour of listview, override padding property with a zero [padding]
return ListView.builder(
padding: EdgeInsets.zero,
itemCount: data.items.length,
itemBuilder: (context, index) {}
);
Looking at your screenshot, the ListView scrolls close to the top of the screen and by default, ListView adds a padding to avoid obstructing the system UI. So a zero padding would remove the extra space.
By default, ListView will automatically pad the list's scrollable
extremities to avoid partial obstructions indicated by MediaQuery's
padding. To avoid this behavior, override with a zero padding
property.
Source : ListView
I solved the issue by adding a padding to my list view like so:
ListView.builder(
padding: EdgeInsets.only(top: 0.0),
...
),
I don't understand why the solution works. If someone can explain the bug, I can accept theirs as the correct answer.
You can wrap your listview with MediaQuery.removePadding
MediaQuery.removePadding(
context: context,
removeTop: true,
child: ListView(...),
)
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
Widget servicesListview() {
return Container(
decoration: new BoxDecoration(color: const Color(0xFFEAEAEA)),
child: Column(
children: <Widget>[
ListView.builder(
scrollDirection: Axis.vertical,
itemCount: menServicesList.length,
itemBuilder: (BuildContext context, int index) {
Text(menServicesList[index].name);
}),
],
));
}
I am implementing listview in my flutter project whenever i call this method list is not visible.The page becomes blank,help me to solve this
I have a same problem.
The ListView.builder don't work inside a Column, this necessary use the Expanded.
The Expanded widget allows you to expand and fill the space with the relative widget.
See this:
child: Column(
children: <Widget>[
Expanded(
child: ListView.builder(
.......
)
)
]
)
Wrap your ListView inside of a Expanded or a Container widget, if you use a Container, you'll need to set a height/width.
This happens because ListView doesn't have a height/width property to edit.
EDIT
Don't forget to return your Text inside the itemBuilder property.
You're missing the return statement in your itemBuilder
itemBuilder: (BuildContext context, int index) {
return Text(menServicesList[index].name);
}),
or
itemBuilder: (BuildContext context, int index) => Text(menServicesList[index].name)),
If you remove Column widget from the ListView, the list will definitely appear
and if you want to give a decoration property to each element of a ListView.
Widget servicesListview() {
return ListView.builder(
scrollDirection: Axis.vertical,
itemCount: menServicesList.length,
itemBuilder: (BuildContext context, int index) {
Container(
decoration: new BoxDecoration(color: const Color(0xFFEAEAEA)),
child: Text(menServicesList[index].name)
);
})
}