height of cards base on widgets height flutter - 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'),
),
),

Related

How can I prevent options view of the RawAutocomplete widget from overflowing on screen in Flutter?

I'm currently using a custom widget similar to this chips_input library. However, I don't want to give the options view (the popup list) a static maximum height. What I want to achieve is to dynamically set a maximum height of screen height - popup y offset. In this way, bottom of the options view will be at the bottom of the screen and all of the content inside the options view will be visible through scrolling. Is there any that I can access the textfield's or options view's offset to calculate the height?
My autocomplete widget looks similar to this:
RawAutocomplete<T>(
...
optionsViewBuilder: Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: textFieldWidth,
child: Material(
elevation: 16,
child: ListView.builder(
shrinkWrap: true,
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final T option = options.elementAt(index);
return suggestionBuilder(context, option);
},
),
),
),
),
);
You can do this by putting a height on your SizedBox that uses MediaQuery to get the screen height:
popupOffset = 20;
RawAutocomplete<T>(
...
optionsViewBuilder: Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: textFieldWidth,
height: MediaQuery.of(context).size.height - popupOffset,
child: Material(
elevation: 16,
child: ListView.builder(
shrinkWrap: true,
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final T option = options.elementAt(index);
return suggestionBuilder(context, option);
},
),
),
),
),
);

make photo bigger when click on flutter

how to make the picture zoomable when the photo is clicked, here's the code I made to display the image
Column(
children: [
image11 != null
? Image.file(
image11,
width: 50,
height: 50,
fit: BoxFit.cover,
)
: Text(" Bagian Belakang"),
Container(
margin: const EdgeInsets.fromLTRB(14, 5, 0, 0),
child: RaisedButton(
padding: EdgeInsets.all(10),
onPressed: () {
pickImage11(ImageSource.camera);
},
child: Icon(Icons.camera),
),
),
],
),
Taking inspiration from this answer Hero animation with an AlertDialog
You can use a Hero widget combined with a PageRouteBuilder to imitate a zoom feature:
Navigator.of(context).push(
PageRouteBuilder(
opaque: false,
barrierDismissible:true,
pageBuilder: (BuildContext context, _, __) {
return Hero(
tag: "zoom",
child: Image.file(...),
);
}
)
);
EDIT: I found barrier dismissable not working and found the solution here: Flutter SizeTransition and PageRouteBuilder not working
You will have to wrap the Hero widget with a defined width and height to get the optimum zoom level.

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....

Remove Padding on CupertinoSliverNavigationBar

I am trying to use CupertinoSliverNavigationBar, actually it's great, but for some reason I can't place the trailing right on the end of navigation bar. I looked up and I (guess, I) found that there's Padding inside it
this is my code
new CupertinoPageScaffold(
child: new CustomScrollView(
slivers: <Widget>[
new CupertinoSliverNavigationBar(
largeTitle: new Text('Tasks'),
trailing: new CupertinoButton(
child: new Icon(AdditionalCupertinoIcons.compose, size: 32.0),
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return new CupertinoAlertDialog();
});
},
padding: EdgeInsets.all(0.0),
),
)
],
),
),
Sadly, no can-do.
Looking at this line of source code, you can see that they are using a Padding at the end, which is _kNavBarEdgePadding, i.e. 16.0. Same for the start.
This means that with the CupertinoSliverNavigationBar you will not be able to remove that Padding because there is no access point to change it. You will have to create your own widget for that.
The _CupertinoPersistentNavigationBar widget contains the Padding and is used by CupertinoSliverNavigationBar, as can be seen here and for completion here.
There is an easy way to move a widget on the screen:
Widget _adjustNavigationBarButtonPosition(Widget button, double x) {
if (button == null) return null;
return Container(
transform: Matrix4.translationValues(x, 0, 0),
child: button,
);
}
Wrap your CupertinoButton with this method and specify an offset. To remove the padding completely, the offset should be 16.0.
You can use Matrix4.translationValues to move a child within the container. In your case x Matrix4.translationValues(12, 0, 0), should be positive to move the trailing to the right.
new CupertinoPageScaffold(
child: new CustomScrollView(
slivers: <Widget>[
new CupertinoSliverNavigationBar(
largeTitle: new Text('Tasks'),
trailing: Container(
transform: Matrix4.translationValues(12, 0, 0),
child : CupertinoButton(
child: new Icon(AdditionalCupertinoIcons.compose, size: 32.0),
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return new CupertinoAlertDialog();
});
},
)
),
)
],
),
),