Minimum reproducible code:
final _controller = ScrollController();
#override
Widget build() {
return NestedScrollView(
headerSliverBuilder: (_, __) => [SliverAppBar(expandedHeight: 300)],
body: ListView.builder(
controller: _controller, // Removing this solves the issue.
itemCount: 100,
itemBuilder: (_, i) => Text('$i'),
),
);
}
If I scroll my ListView, the SliverAppBar doesn't scroll but if I remove the controller property then it does scroll.
So, how can I use the controller and make the SliverAppBar to scroll with the ListView (i.e. the standard behavior)?
Note: I don't want to use the CustomScrollView as my tree hierarchy won't let me make use of it that well.
You should make sure that the child is wrapped
final _controller = ScrollController();
#override
Widget build() {
return NestedScrollView(
headerSliverBuilder: (_, __) => [SliverAppBar(expandedHeight: 300)],
body: ListView.builder(
//add this to the child ListView
shrinkWrap: true
controller: _controller, // Removing this solves the issue.
itemCount: 100,
itemBuilder: (_, i) => Text('$i'),
),
);
}
Just move the scroll controller to NestedScrollView like this:
Widget build() {
return NestedScrollView(
headerSliverBuilder: (_, __) => [SliverAppBar(expandedHeight: 300)],
body: ListView.builder(
//add this to the child ListView
shrinkWrap: true,
itemCount: 100,
itemBuilder: (_, i) => Text('$i'),
),
controller: _controller,
);
}
That worked for me, I had a waterfalls flow using the scroll controller. and I need the sliver appear style.
Related
I have a DraggableScrollableSheet that has a DraggableScrollableController. I'm calling .animateTo() on the DraggableScrollableController. Is there any way to tell outside of the sheet, in another widget maybe, that the sheet is animating? Some kind of isAnimating type property where the default is false, then when you call animateTo and you check this property it is true and when it completes, back to false?
you can wrap it with NotificationListener:
this will show the extent of your draggableScrollableSheet.
NotificationListener<DraggableScrollableNotification>(
onNotification: (notification) {
print("${notification.extent}");
},
child: DraggableScrollableSheet(
initialChildSize: .70,
minChildSize: .70,
builder:
(BuildContext context, ScrollController scrollcontroller) {
return Container(
child: ListView.builder(
controller: scrollcontroller,
itemCount: widget.songs.length,
itemBuilder: (BuildContext context, int index) {
return buildSongRow(widget.songs[index]);
}),
);
}),
)
then you can set some logic like this :
bool isAnimating = notification.extent != notification.maxExtent;
please try it and tell me.
I have my ListView.builder inside Expanded widget which render widgets correctly on the screen but I cannot scroll the widgets rendered by it.
Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: getPostsForUid(),
builder: (_, snap) {
return Expanded(
child: ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: snap.data.length,
itemBuilder: (_, index) {
if (snap.data[index]['post_type'] == 'real_estate') {
return realEstate(snap, index);
}
else if (snap.data[index]['post_type'] == 'video_sharing') {
return videoSharing(snap, index);
}
else {
return Text('');
}
},
),
);
},
),
);
}
Try using ScrollPhysics() class,
physics: ScrollPhysics(),
here is the link for reference for the same.
You should set your physics to AlwaysScrollableScrollPhysics().
The docs state the following:
Scroll physics that always lets the user scroll.
This overrides the default behavior which is to disable scrolling when there is no content to scroll. It does not override the handling of overscrolling.
On Android, overscrolls will be clamped by default and result in an overscroll glow. On iOS, overscrolls will load a spring that will return the scroll view to its normal range when released.
Here is an image of "overscroll glow" for you to understand what that means.
Consider using shrinkWrap: false to expand your contents in case they are bounded.
Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: getPostsForUid(),
builder: (_, snap) {
return Expanded(
child: ListView.builder(
physics: AlwaysScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: snap.data.length,
itemBuilder: (_, index) {
if (snap.data[index]['post_type'] == 'real_estate') {
return realEstate(snap, index);
}
else if (snap.data[index]['post_type'] == 'video_sharing') {
return videoSharing(snap, index);
}
else {
return Text('No data available.');
}
},
),
);
},
),
);
}
See the docs:
https://api.flutter.dev/flutter/widgets/AlwaysScrollableScrollPhysics-class.html
Add Physics:AlwaysScrollable() in your Listview.
Does anyone know if there is a way to remove the PageView color that occurs when the user reaches the end of the items?
this is an image that describes what I mean
Click here
PageView.builder(
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
controller: _controller,
itemCount: 4,
itemBuilder: (BuildContext context, int index) {
_isValid = false;
return [
SizedBox.expand(...),
SizedBox.expand(...),
SizedBox.expand(...),
SizedBox.expand(...),
][index];
},
)
I found the complete and right answer here: How to remove scroll glow?
This effect is provided by ScrollBehavior. You need to provide your custom ScrollBehavior and wrap it inside a ScrollConfiguration.
class CustomScrollBehavior extends ScrollBehavior {
#override
Widget buildViewportChrome(
BuildContext context, Widget child, AxisDirection axisDirection) {
return child;
}
}
To remove the effect in your PageView
ScrollConfiguration(
behavior: CustomScrollBehavior(),
child: PageView.builder(
...
),
)
above one is not worked for me , after the new flutter v2 ( sdk 2.8.1),
NotificationListener<OverscrollIndicatorNotification>(
onNotification: (overscroll) {
overscroll.disallowIndicator();
return true;
},
child: SingleChildScrollView(
)
)
In flutter we have a widget DraggableScrollableSheet. Now I want the current position or the current size of the child while it is dragging. There is currently no way to get that value. It gives a ScrollController in its builder method but that is for when the list is scrolling and not when its being dragged. So is there another way by which I can track the current drag position of the list?
I tried adding NotificationListener but that only gives me dragstartnofification and dragendnotification and nothing for dragupdate:
DraggableScrollableSheet(
initialChildSize: .70,
minChildSize: .70,
builder:
(BuildContext context, ScrollController scrollcontroller) {
return NotificationListener(
onNotification: (notification) {
print("$notification");
},
child: Container(
child: ListView.builder(
controller: scrollcontroller,
itemCount: widget.songs.length,
itemBuilder: (BuildContext context, int index) {
return buildSongRow(widget.songs[index]);
}),
),
);
}),
I found the solution to this. Flutter team updated the ScrollableDraggableSheet class in the Flutter v1.7.3. They added a class called DraggableScrollableNotification which you can listen to to get the current extend of the child when dragging.
NotificationListener<DraggableScrollableNotification>(
onNotification: (notification) {
print("${notification.extent}");
},
child: DraggableScrollableSheet(
initialChildSize: .70,
minChildSize: .70,
builder:
(BuildContext context, ScrollController scrollcontroller) {
return Container(
child: ListView.builder(
controller: scrollcontroller,
itemCount: widget.songs.length,
itemBuilder: (BuildContext context, int index) {
return buildSongRow(widget.songs[index]);
}),
);
}),
)
in the above sample notification.extent will give you the current extent(position) of the child when dragging.
Note: this is currently in the master channel and not in the stable
channel. Switch to the master channel by running flutter channel master
and then flutter upgrade to make it work for now.
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)
);
})
}