DraggableScrollableSheet sets initialChildSize without animation - flutter

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?

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.

modalBottomSheet + ListView, how to sync scroll?

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"),
),
);
},
);
},
);

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.

Nested ScrollView inside Slidable panel widget

I have a panel widget that can be dragged vertically in and out from the bottom of the screen. In that panel widget, there is a ListView that is scrollable.
What I'm trying to achieve is, having the panel handle the drag for opening and closing without the nested listview interfering. Once, the panel is open, the listview become scrollable and if the listview is scrolled down while already at the top, the panel handle the gesture instead and closes.
Like so:
I tried to enable/disable scrolling physics on the ListView based on the Panel position but turned out not to be possible that way.
Any ideas ? :)
You can achieve that with DraggableScrollableSheet.
Here is a quick example of how you can use it:
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Center(child: Text('Some content')),
DraggableScrollableSheet(
minChildSize: 0.2,
initialChildSize: 0.2,
builder: (context, scrollController) => Container(
color: Colors.lightBlueAccent,
child: ListView.builder(
controller: scrollController,
itemCount: 20,
itemBuilder: (context, index) => SizedBox(
height: 200,
child: Text('Item $index'),
),
),
),
),
],
),
);
}

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.