modalBottomSheet + ListView, how to sync scroll? - flutter

I have a modalBottomSheet with a scrolling list view inside of it.
I want for the scroll control to be transferred to the bottom sheet when the listView reaches the top, so that it can be dragged to dismiss.
Now, the listView gets to the top and even if I keep dragging the bottom sheet will not be dismissed on drag.
Thank you!

Try this way
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) {
return DraggableScrollableSheet(
maxChildSize: 1,
initialChildSize: .5,
expand: false,
builder: (context, scrollController) {
return ListView.builder(
itemCount: 44,
controller: scrollController,
itemBuilder: (context, index) => ListTile(
title: Text("item $index"),
),
);
},
);
},
);

Related

How to determine if a DraggableScrollableController is animating in Flutter?

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.

showModalBottomSheet how can i navigate with data

When the item in the listview is clicked, I want to move the information to the bottom sheet, but I couldn't find the way.
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => customBottomSheet(context),
),i tried but it didn't work how can i solve this problem
return Expanded(
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: coinListForDisplay.length,
itemBuilder: (context, index) {
return InkWell(
onTap: (() {
customBottomSheet(context);
}),
child: ListViewCard(
name: coinListForDisplay[index].name,
symbol: coinListForDisplay[index].symbol,
imageUrl: coinListForDisplay[index].imageUrl,
price:
coinListForDisplay[index].price.toDouble(),
change:
coinListForDisplay[index].change.toDouble(),
changePercentage: coinListForDisplay[index]
.changePercentage
.toDouble(),
),
);
}),
);```
You can pass data in parameters like this.
In you custom bottom sheet, use
CustomBottomSheet(BuildContext context,yourData){
//Your code
}
And in your onTap function use
CustomBottomSheet(context,yourData);

DraggableScrollableSheet sets initialChildSize without animation

I have the following widget structure. And my question: Is it possible to my DraggableScrollableSheet sets his initial size with scroll animation?
...
child: WillPopScope(
onWillPop: onWillPop,
child: DraggableScrollableSheet(
initialChildSize: widget.convertSnapValue(widget.initialExpansion),
snap: true,
snapSizes: _snapSizes,
minChildSize: 0,
controller: _sheetController,
builder: (context, scrollController) => _content(scrollController),
),
),
);
u can set initialsize:0 and after rebuild finish, animateTo size that u want with controller?

My modalBottomSheet is draggable just on edges

I have a DraggableScrollableSheet inside of a showModalBottomSheet builder. I have set isDismissible: true for modal sheet but my widget is draggable just on edges. That is because I have a ListView inside of DraggableScrollableSheet.
What I should do for when the list is overscrolled on top the drag to start?
Here goes my code:
showModalBottomSheet<void>(
context: context,
isScrollControlled: true,
isDismissible: true,
backgroundColor: Colors.transparent,
enableDrag: true,
builder: (BuildContext context) {
return StackedSheet(
backgroundColor: backgroundColor,
onBackgroundColor: onBackgroundColor,
padding: padding,
minChildSize: minChildSize,
maxChildSize: maxChildSize,
onClose: onClose,
child: SafeArea(
top: false,
child: child,
),
);
},
);
Where StackedSheet is:
LayoutBuilder(
builder: (context, constraints) {
return DraggableScrollableSheet(
key: Key('$_childSize'),
initialChildSize: min(_childSize, widget.maxChildSize),
minChildSize:
min(_childSize - _childSize * 0.2, widget.minChildSize),
maxChildSize: min(_childSize, widget.maxChildSize),
expand: false,
builder: (
BuildContext context,
ScrollController scrollController,
) {
return ListView.separated( ...blah blah)
}
Here is a GIF:
Instead of bouncing, my desire is to start to be dragged down.
In my opinion you can use scroll controller to dismiss bottomsheet on reaching top something like this
if (_controller.offset <= _controller.position.minScrollExtent &&
!_controller.position.outOfRange) {
.....
.....
);
}
You can stop list from bouncing at top using shrinkWrap=true in Listview.
And to dismiss the bottomsheet you can refer to this stackoverflow post
I haven't tried this code but hopefully it will help you in some way.
Also, I think it will look good if you will keep it the way it is now by inserting a little "-" at top on right side of "X" ,on which user can touch to slide down.

DraggableScrollableSheet doesn't give the current position of the sheet when dragging

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.