How to decrease the bottomsheet height dynamically in flutter? - flutter

i am using showModalBottomSheet and given the height of 90% at start. There are two tabs(repeat and onetime) inside bottomsheet, repeat tab has a lot of contents and it is showing perfectly fine with 90% height. But when i tab on onetime tab, i want to decrease the size of bottomsheet to 40% because it does not have more content in it and it does not look nice. But i am unable to change dynamically the height of bottom sheet on pressing onetime tab button.
Can anyone help me how can i achieve this functionality in flutter?

You can use the following code by replacing PutYourWidgetHere() with your custom widget.
void showBottomSheet() {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (BuildContext context) {
return SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: PutYourWidgetHere(),
));
});
}

dynamically the height and make content in center
showCupertinoModalBottomSheet(
expand: false,
enableDrag: true,
isDismissible: true,
barrierColor: ColorUtils.disableBackground.withAlpha(128),
backgroundColor: ColorUtils.enableBackground,
topRadius: Radius.circular(SizeUtils.minBlock * 4),
context: globalKey.currentState!.context,
builder: (builder) {
return Padding(
padding: EdgeInsets.all(SizeUtils.minBlock * 8),
child: Container(
constraints: BoxConstraints(
minHeight: SizeUtils.blockHeight * 30,
maxHeight: SizeUtils.blockHeight * 60),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [SingleChildScrollView(child: widget)])));
});

Related

height of cards base on widgets height flutter

I want to set the height for my cards based on the height of the widgets in it.
I use globalKey and set it in my widget but return null.
can anyone help me how can I do that?
final GlobalKey _Key = GlobalKey();
showModalBottomSheet(
context: context,
useRootNavigator: true,
isScrollControlled: true,
isDismissible: true,
enableDrag: true,
builder: (context) {
return Container(
key : _key,
child: ListView(
shrinkWrap: true,
padding: EdgeInsets.zero,
children: [
PressWidget(),
PaddingButtonCard(),
],
),
);
},
);
when I print _Key.currentContext?.findRenderObject().size , return null.
A Widget like a card should automatically wrap it's contents, so unless the contents have an unconstrained height (like a ListView or Expanded widget), you shouldn't need measuring or such techniques to achieve this.
Try, as a test, putting a Container with a set height inside your Card, and observe how the card automatically sizes itself:
Card(
child: Container(
height: 40,
width: double.maxFinite,
color: Colors.purple,
child: Text('Purple Card'),
),
),

OpenContainer animation not working in a SingleChildScrollView

This is my code:
child: SingleChildScrollView(
padding:
const EdgeInsets.only(top: 20, bottom: 20, left: 15, right: 15),
child: Column(
children: <Widget>[
OpenContainer(
transitionType: ContainerTransitionType.fadeThrough,
closedBuilder: (BuildContext _, VoidCallback opencontainer) {
return GestureDetector(...);
},
openBuilder: (BuildContext _, VoidCallback __) {
return SizedBox(
height: 500,
child: Text("Works"),
);
},
),
...
The SingleChildScrollView is also within a container for alignment in the page. GestureDetector has an InkWell within it which has a Card.
I have the animations package installed and working, what is going wrong here?
Perks of being a programmer; due to going through a long process of getting widgets to work by putting them within other widgets, I just copied and pasted them into the closedBuilder.
The simple solution was to just take the Card and place it within the return statement of the closedBuilder, without its GestureDetector and InkWell (of course, both of them have onTaps as well, would make things very wonky).

Flutter Bottom Sheet Dialog Not Resizing in some cases

I have a Custom BottomSheetDilaog in a flutter.
There are two ways this dialog can be open
1)Via Floating Button above Bottom navigation that is attached To HomeMainScreen
2)Via Button on HomeScreen Tab that is the first widget in Bottom navigation.
When a user clicks on the floating button the TextFieldForm Resize as the keyboards open.
But when it is open via HomeScreen Tab Button then Its root view is Resize and not the Bottom sheet Dialog.
showModalBottomSheet(
backgroundColor: foreground_color,
isScrollControlled: true,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.vertical(top: Radius.circular(20.r))),
context: context,
builder: (builder) {
return AnimatedPadding(
duration: const Duration(milliseconds: 250),
curve: Curves.easeInOutSine,
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: SafeArea(
maintainBottomViewPadding: true,
child: Wrap(
children: [
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
How to make sure that in both cases it resize as expected when the keyboard is opened.
Sample Code
https://github.com/parmarravi/bottom_sheet_bug

Flutter Simple Dialog content going off the screen

I have a dialog I am trying to wrap the content in the dialog however I am having few problems
1)Use of wrap does not guarantee that content is in the alert dialog box
2)alignment of content is not center.
I have tried all possible alignment and it does not work.
While using column stretch the widget I thought maybe using wrap will work . But it does not.
Any solution?
With Column
With Colored Container in a wrap to check the issue and with size box with defined width of display * 0.25 so that text does not go away from screen
Code
showDialog(
barrierDismissible: false,
barrierColor: Colors.black26,
context: context,
builder: (context) {
return StatefulBuilder(
builder: (context, setState) {
return AlertDialog(
contentPadding: EdgeInsets.all(20),
content: Wrap(
direction: Axis.vertical,
alignment: WrapAlignment.spaceAround,
runAlignment: WrapAlignment.center,
crossAxisAlignment: WrapCrossAlignment.center,
runSpacing: 10,
children: [
Lottie.asset(
Constants.location_anim,
height: displaySize.height * 0.25,
repeat: true,
reverse: true,
animate: true
),
Text(locationMsgTextView,softWrap: true,),
getLocationDeniedWidget(context,state),
],
),
elevation: 3,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
);
},
);
});

How to customize a dialog's position, size and background?

I have a home screen with a FAB and when it's pressed I want to display a dialog for user to input.
Currently I am using showDialog() with SimpleDialog.
showDialog(
context: context,
builder: (BuildContext context) {
return SimpleDialog(
title: NormalText('New Counter Item'),
contentPadding: EdgeInsets.fromLTRB(24.0, 0.0, 24.0, 24.0),
children: <Widget>[
Container(
...
)
],
);
}
);
But, I can't seem to customise almost anything with it (smaller, corner-curved and positioned lower on the screen). AlertDialog seems to be the same.
Is there anyway to customise those attributes?
return showDialog<void>(
barrierDismissible: true,
context: context,
builder: (BuildContext context) {
return new Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(0),
child: new Container(
height: 100,
width: MediaQuery.of(context).size.width,
color: Colors.purple,
child: new Column(
children: <Widget>[
new Text(
'custom dialog text',
style: new TextStyle(
fontSize: 14,
color: Colors.white,
),
),
],
),
),
)
],
);
},
);
hope this helps,
thanks
SimpleDialog and AlertDialog are meant to cater to a specific set of needs. They have certain levels of customization, but ultimately they are meant to just show simple pop-up dialogs that give the user some information and prompt for a dialog response (i.e. "Yes", "No", "Cancel", "Save", etc.).
If you want to have a more customizable pop-up dialog, you will need to create your own. On the plus side, though, it's really quite simple. Have the builder in showDialog return a Dialog widget with a child set to whatever you want:
showDialog(
context: context,
builder: (BuildContext cxt) {
return Dialog(
child: Container(
...
),
);
},
);
Obviously you are going to need to recreate things like the title bar and action bar, but you can either crack open the source code of SimpleDialog and AlertDialog and copy what they have there or you can roll your own solution.
Despite what the accepted answer says; there are ways to customise the SimpleDialog in the ways that you have requested.
Size
The SimpleDialog will grow in width/height depending on the child and how it is padded. The below code will generate a dialog of width 336 and height 300:
showDialog(
context: context,
builder: (BuildContext context) {
return SimpleDialog(
insetPadding: EdgeInsets.zero,
titlePadding: EdgeInsets.zero,
contentPadding: EdgeInsets.zero,
children: [
Container(
width: 300,
height: 300,
),
],
);
},
);
Not sure what the added 36 pixels to the width is; but this demonstrates that size can be customised.
Corners
Corners can be customised using the shape property. The below code shows a green border with a rounded edge of 4 pixels:
showDialog(
context: context,
builder: (BuildContext context) {
return SimpleDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4.0),
side: BorderSide(
color: Colors.green,
),
),
/* ... */
);
},
);
Position
I've found that I can nudge the dialog up and down the page by using the insetPadding property. This defines the minimum amount of space required between the edge of the screen and the dialog. Although it's a bit cumbersome, if you knew the size of the screen and the size of the dialog, you could nudge the dialog's position with some simple math.
Given a screen height of 1920px, and a dialog height of 300px, the below code should place your dialog 100px from the top edge of your screen, rather than bang in the centre:
showDialog(
context: context,
builder: (BuildContext context) {
return SimpleDialog(
insetPadding: EdgeInsets.only(bottom: 1520),
/* ... */
);
},
);
This is because I've requested a minimum padding between the bottom edge of the screen and the dialog; and the only position for the dialog to exist under this stipulation is nearer the top.
No. These are not designed to be customizable. They were made to respect Material Design principles in mind.
If you want a custom design, you can make your own modal based of Align and/or DecoratedBox
It's not as scary as you might expect.
You only need to clone Dialog.dart, and
replace the Center widget with an Align.
Of course also rename stuff; e.g. MyDialog, myShowDialog, MySimpleDialog.
Yep, it's that easy.
And if you're on a roll, how about adding the Align widget's alignment parameter as an extra...
You can actually modify it's position (only height) by adding a SingleChildScrollView() in the builder + a padding (for the offset from the top) as follows:
showDialog<String>(
context: context,
builder: (ctxDialog) =>
SingleChildScrollView(
child: Padding(
padding: EdgeInsets.only(top: 150.0),
child: AlertDialog()
)
)
);
Here is a clean solution, If for some reason you have a TextField/TextFormField and in there you have a onsubmit property then you can follow:
onSubmit: () {
showDialog(
context: context,
builder: (context){
return WillPopScope(
onWillPop: () { return Future(() => false); }, // this will prevent going back
child: AlertDialog(
content: Row(
children: [
progressWidget(),
Container(margin: EdgeInsets.only(left: 10.0),child:Text("Loading" )),
],),
)
);
}
);
yourCallToMethod.whenComplete((){
Navigator.of(context).pop();
});
},
BENEFIT?
When the showAlert is shown if someone tap on the screen randomly or aggressively then the screen goes back. This prevents that behavior and only closes the showAlert when your function completes.
:- we can change vertical position of dialog boxes by give bottom
insetPadding like
insetPadding: EdgeInsets.only(bottom: XX);
:- And horizontal position by Horizontal padding or left
insetPadding: EdgeInsets.symmetric(horizontal:XX);
or
insetPadding: EdgeInsets.only(left: XX,right:YY);
I found the answer to it here. Thanks to #CopsOnRoad
Using showGeneralDialog
Scaffold(
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
showGeneralDialog(
context: context,
barrierColor: Colors.black54,
barrierDismissible: true,
barrierLabel: 'Label',
pageBuilder: (_, __, ___) {
return Align(
alignment: Alignment.bottomLeft,
child: Container(
color: Colors.blue,
child: FlutterLogo(size: 150),
),
);
},
);
},
),
)
Solved that with wrapping dialog body in Stack and Positioned
Stack(
children: [
Positioned(
left: 100, // left coordinate
top: 100, // top coordinate
child: YOUR_DIALOG....