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.
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 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"),
),
);
},
);
},
);
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);
Got the basic listview working with this code:
body: GetX<LokationListeCtrl>(
builder: (ctrl) => ListView.separated(
separatorBuilder: _separatorBuilder,
itemCount: ctrl.lokationListe.length,
itemBuilder: (BuildContext context, int index) {
return _lokationTile(ctrl.lokationListe.elementAt(index));
},
),
),
Ok great, so now I'll just add another list by wrapping the whole thing in a multiple child widget, but even before doing that, I'm already stuck trying to get the first list working:
body: Column(
children: [
GetX<LokationListeCtrl>(
builder: (ctrl) => ListView.separated(
separatorBuilder: _separatorBuilder,
itemCount: ctrl.lokationListe.length,
itemBuilder: (BuildContext context, int index) {
return _lokationTile(ctrl.lokationListe.elementAt(index));
},
),
),
],
),
Here using a Column, but it applies to all widgets with multiple children. The itemBuilder code is simply newer executed.
It seems like a simple and usefull thing to be able to do - the question is HOW to have multiple list in body, the "GetX way" ?
Found a solution. If we introduce a new Scaffold and wrap it in an Expanded, then GetX stops beeing an insulted little boy, and starts smiling again:
body: Column(
children: [
Expanded(
child: Scaffold(
body: MyBodyPadding(
// add space between appbar and first ListTile
child: GetX<LokationListeCtrl>(
builder: (ctrl) => ListView.separated(
separatorBuilder: _separatorBuilder,
itemCount: ctrl.lokationListe.length,
itemBuilder: (BuildContext context, int index) {
return _lokationTile(
ctrl.lokationListe.elementAt(index));
},
),
),
),
),
),
],
),
Added this plugin to flutter project. Here is my following code
body: SlidingUpPanel(
backdropEnabled:true,
panelSnapping:true,
defaultPanelState:PanelState.CLOSED,
panel:ListView.separated(
itemCount:2,
itemBuilder: (BuildContext context, int index){
return Text('ass');
},
separatorBuilder:(BuildContext context, int index){return Divider();},
collapsed:Container(),
),
The problem is when I fully open the slider , I cannot slide it back. If remove Listview it works fine. So how can I slide it back with listview?
This has been fixed in v1.0.0 of sliding_up_panel. If you update your pubspec.yaml to include v1.0.0 of sliding_up_panel and follow this guide, you should be able to get the desired behavior.
Here's what it would look like for your layout:
body: SlidingUpPanel(
backdropEnabled: true,
panelSnapping: true,
defaultPanelState: PanelState.CLOSED,
panelBuilder: (ScrollController sc) => ListView.separated(
controller: sc,
itemCount: 2,
itemBuilder: (BuildContext context, int index){
return Text('ass');
},
separatorBuilder: (BuildContext context, int index){
return Divider();
},
),
collapsed: Container(),
)