My modalBottomSheet is draggable just on edges - flutter

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.

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

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?

How to pop CupertinoPageRoute with swipe down?

Currently I'm using the following Code to get a FadeInTransition from the bottom when opening the page.
Navigator.of(context).push(
CupertinoPageRoute(
fullscreenDialog: true,
maintainState: true,
builder: (BuildContext context) => Routines(),
)
)
Normally in iOS you can just swipe left to close the current page. Is there an easy way to swipe down to pop the current page or do I have to implement a custom field with a GestureDetector()?
The goal is to have a closing transition like in the GIF below using a swipe down at the top
I considered using a DraggableScrollableSheet but I don't want to slide the Page into view from the bottom.
I ended up solving it with an DraggableScrollableSheet:
onPressed: () {
showModalBottomSheet(
backgroundColor: Colors.transparent,
context: context,
isScrollControlled: true,
builder: (BuildContext context) {
return Routines();
},
);
},
and Wrapping my new Page with:
return DraggableScrollableSheet( //TODO make same for Entries
expand: false,
initialChildSize: 1.0,
minChildSize: 0.8,
builder: (context, scrollController) {
return Page2();
}
);

bottom sheet with initial height half of screen and if it scroll then height is increase to full screen

I have a bottom sheet with below code in where i put a height 300.0 but I want increase height to full screen when user scroll ..how can i do that ..please
void _showBottomSheet() {
setState(() {
_showPersBottomSheetCallBack = null;
});
_scaffoldKey.currentState
.showBottomSheet((context) {
return new Container(
height: 300.0,
color: Colors.greenAccent,
child: new Center(
child: new Text("Hi BottomSheet"),
),
);
})
.closed
.whenComplete(() {
if (mounted) {
setState(() {
_showPersBottomSheetCallBack = _showBottomSheet;
});
}
});
}
The flutter package bottom sheet is not meant to occupy the full screen, though a little tweak can produce the behavior you expect.
If you look at the BottomSheet constructor, you will find the following:
#override
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
return new BoxConstraints(
minWidth: constraints.maxWidth,
maxWidth: constraints.maxWidth,
minHeight: 0.0,
maxHeight: constraints.maxHeight * 9.0 / 16.0
);
}
If you remove the 9.0/16.0 height constraint, the bottom sheet will occupy the full screen height.
If all you want is a full-screen bottom sheet (as #edmond demonstrates), you can now use isScrollControlled: true without having to maintain your own hacked version of BottomSheet.
Regardless, the question is about first loading the sheet to half height, with the ability to extend to full height on scroll. For that fine-grained control, you'll still want to use isScrollControlled: true, but also you can wrap the content of the modal sheet in DraggableScrollableSheet. This Github comment shows you how to do it, which I'm copying here for reference:
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (BuildContext context) {
return DraggableScrollableSheet(
initialChildSize: 0.5, // half screen on load
maxChildSize: 1, // full screen on scroll
minChildSize: 0.25,
builder: (BuildContext context, ScrollController scrollController) {
return Container(
color: Colors.white,
child: ListView.builder(
controller: scrollController,
itemCount: 25,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text('Item $index'));
},
),
);
},
);
},
);