Column take all the screen - flutter

I'm making a flutter app in which I use an AlertDialog widget
Here is a screen in which you can understand where the problem is :
Here is a piece of my code used for that
showDialog(
context: context,
builder: (BuildContext context) {
// return object of type Dialog
return AlertDialog(
title: Text('Ajouter un ingrédient'),
content: new Column(
children: <Widget>[
Container(
child: DropDownButtonIngredients(),
),
Container(
child: new TextField(
autofocus: false,
decoration: new InputDecoration(
labelText: 'Nom', hintText: 'Frite, Steak, Salade ...'),
onChanged: (value) {
newIngr = value;
},
)),
],
),
actions: <Widget>[
FlatButton(
child: Text('Ok'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
Note : I already tried to remove the DropDownButtonIngredients container, nothing new, same for the other container

Set mainAxisSize to MainAxisSize.min:
Column(
mainAxisSize: MainAxisSize.min,
...
);

Related

Responsive Container in flutter

I have a Single child scroll view with child container which I defined the height and width
The problem is when I click on textfield the button is hidden/does not go up. How do I make the height responsive?
#override
Widget build(BuildContext context) {
_width = MediaQuery.of(context).size.width;
_height = MediaQuery.of(context).size.height;
return SingleChildScrollView(
controller: _scrollController,
child: Container(
width: _width,
height: _height,
child: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Expanded(
child: StreamBuilder(
stream: userBloc.user$,
builder: (BuildContext context, AsyncSnapshot snapshot) {
User user = snapshot?.data;
String maskedEmail = _getMaskedEmail(user);
return Column(
children: <Widget>[
widget.instruction != null
? Container(
padding: GenericAssets.paddingSymV10,
child: Text(
widget.instruction,
style: GenericAssets.defaultText,
textAlign: TextAlign.center,
))
: Container(),
(maskedEmail?.isNotEmpty ?? false)
? Column(
children: <Widget>[
Padding(
padding: GenericAssets.paddingSymV10,
child: Text(
S.of(context).strProvideMaskedEmail,
style: GenericAssets.defaultText,
textAlign: TextAlign.center),
),
Padding(
padding: GenericAssets.paddingSymV10,
child: Text(maskedEmail,
style: GenericAssets.defaultText,
textAlign: TextAlign.center),
)
],
)
: Container(),
Container(
child: TextFormField(
style: GenericAssets.defaultText18,
controller: _emailController,
focusNode: _emailFocusNode,
keyboardType: TextInputType.emailAddress,
inputFormatters: [LowerCaseTextFormatter()],
decoration: InputDecoration(
labelText:
S.of(context).fieldEmail.toUpperCase(),
labelStyle: GenericAssets.textFormLabel,
contentPadding:
GenericAssets.textFormFieldSpacing),
validator: (value) {
if (value.isEmpty) {
return S.of(context).msgTextFieldMandatory(
S.of(context).fieldEmail);
}
if (!isEmail(value) ||
!HelperFunctions.isPatternValid(
ProjectConstants.emailPattern, value)) {
return S.of(context).msgPleaseEnterAValidValue(
S.of(context).fieldEmail);
}
return null;
},
),
),
Padding(
padding: GenericAssets.paddingSymV5,
child: PasswordField(
_passwordController,
checkFormat: false,
showPassword: true,
focusNode: _passwordFocusNode,
),
)
],
);
},
),
),
FullWidthButton(
S.of(context).strLogin,
() async {
LoggerService.log(
LogEventType.ButtonPress,
LogDetails(
buttonName: 'Login', displayName: 'Login Screen'));
if (_formKey.currentState.validate()) {
widget.onSubmit(context, widget.authenticationManager,
_passwordController.text, _emailController.text);
}
},
),
InkWell(
onTap: onForgotPassword,
child: Padding(
padding: GenericAssets.padding10,
child: Text(
S.of(context).strForgotPassword,
style: GenericAssets.footNoteLink,
),
),
),
InkWell(
onTap: onResetApp,
child: Padding(
padding: GenericAssets.padding10,
child: Text(
S.of(context).btnResetApplication,
style: GenericAssets.footNoteLink,
),
),
)
],
),
),
),
);
}
I want to show the buttons and other widgets when keyboard is shown.
This is a widget I'm calling it from
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () => HelperFunctions.logBackpress('Login Screen'),
child: Scaffold(
appBar: AppBar(title: AppBarTitle(S.of(context).strLogin)),
body: StreamBuilder(
stream: manager.loginState$,
builder: (BuildContext context, AsyncSnapshot snapshot) {
bool isLoading = snapshot?.data?.isLoading ?? false;
return Stack(
children: <Widget>[
LoginForm(onSubmit, authenticationManager: manager),
LoadingIndicator(isLoading)
],
);
},
),
),
);
}

How to call flutter dialog from separate class?

I need to separate my dialog to separate widgets an call from anywhere on some button click. Now my code looks like:
import 'package:flutter/material.dart';
class PlacesListScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return _Map();
}
}
class _Map extends StatefulWidget {
#override
_MapState createState() => _MapState();
}
class _MapState extends State<_Map> {
final _titleController = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('App name'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.add),
onPressed: () {
return showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: Text(
"Dialog title",
textAlign: TextAlign.center,
),
content: TextField(
decoration: InputDecoration(labelText: 'Title'),
controller: _titleController,
),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(ctx).pop();
},
child: Text("No"),
),
FlatButton(
onPressed: () {
return showDialog(
context: context,
builder: (ctx) => StatefulBuilder(builder:
(BuildContext context, StateSetter setState) {
return AlertDialog(
title: Text(
"Second subdialog title",
textAlign: TextAlign.center,
),
content: Container(
width: 150,
height: 200,
decoration: BoxDecoration(
border:
Border.all(width: 1, color: Colors.grey),
),
child: Text('Here will be file'),
alignment: Alignment.center,
),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(ctx).pop();
},
child: Text("No"),
),
FlatButton(
onPressed: () => Text('Here I will work with state'),
child: Text("Yes"),
),
],
);
}),
);
},
child: Text("Yes"),
),
],
),
);
},
),
],
),
body: Text('App body here'),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
FloatingActionButton(
onPressed: () => Text('Here will be called dialog function'),
child: Icon(Icons.add, color: Colors.white),
backgroundColor: Colors.green,
heroTag: 'mapZoomIn',
),
],
),
);
}
}
Now how I can this part of code (calling dialog) separate to another widget and call then using created widget.
showDialog(
context: context,
builder: (ctx) => StatefulBuilder(builder:
(BuildContext context, StateSetter setState) {
return AlertDialog(
title: Text(
"Second subdialog title",
textAlign: TextAlign.center,
),
content: Container(
width: 150,
height: 200,
decoration: BoxDecoration(
border:
Border.all(width: 1, color: Colors.grey),
),
child: Text('Here will be file'),
alignment: Alignment.center,
),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(ctx).pop();
},
child: Text("No"),
),
FlatButton(
onPressed: () => Text('Here I will work with state'),
child: Text("Yes"),
),
],
);
}),
);
Firstly, you can refactor your StatefulBuilder(builder: (BuildContext context, StateSetter setState) { return AlertDialog(... into one separate widget like MyFancyDialog extends StatefulWidget. Then just call showDialog(..., MyFancyWidget()) when you need it.
Secondly, if you do not want the first method, you can extract the whole showDialog(...) into a function like void showMyFancyDialog() { showDialog... }. Is it also OK, since in dart functions are first class.
Did you try to create a new Stateful widget class at the bottom of your code and try to call that widget? If you didn't try that,
Go to under of your code and create a new Stateful class. (Let's say that myDialog)
Add the code that you want to call, inside of your "myDialog" widget
Go for where you want to call that code and try to call that class.
Hope this works for you.
Create a separate file. Import material package.
then create "Widget myDialog(context){ // paste your showDialog code here }"
Now your myDialog widget has been ready for using anywhere on whole project just import and call it.
When you call it pass BuildContext in its argument.
Its work for me.

alertDialog won't appear in flutter

I have a list item when long pressed executes _selectionAlert which have two buttons one for delete and one for edit(refer image). Delete works fine but when I press on edit it should execute _editAlert which should show another alertDialog but when I click it nothing happens what's the problem here?
This is responsible to show alert dialog in _selectionAlert
TextButton( // refer code bellow
child: Text('Edit', style: TextStyle(color: Colors.grey)),
onPressed: (){
_editAlert();
Navigator.of(context).pop();
},
)
This bellow code runs when item is long pressed:
void _selectionAlert(){
var selItem = AlertDialog(
title: Text('What you want to do?'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextButton( // ignore this it is for deletion this works fine
child: Text('Delete', style: TextStyle(color: Colors.red)),
onPressed: (){
_deleteItem();
Navigator.of(context).pop();
},
),
TextButton(
child: Text('Edit', style: TextStyle(color: Colors.grey)),
onPressed: (){
_editAlert(); // this line should call _editAlert
Navigator.of(context).pop();
},
)
],
),
);
showDialog(
context: context,
builder: (BuildContext context){
return selItem;
}
);
}
Representation of above code:
void _editAlert(){ // edit alertDialog
var editItem = AlertDialog(
title: Text('Edit'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
decoration: InputDecoration(
hintText: 'Edit Item',
),
controller: addeditem,
),
TextButton(
child: Text('Done'),
onPressed: (){
_editItem();
Navigator.of(context).pop();
}
)
],
),
);
showDialog(
context: context,
builder: (BuildContext context){
return editItem;
}
);
}
PS: edit button is of grey color the button surely is clickable and I am testing on google chrome.
Regards
Try to add return statement at your _editAlert method
_editAlert(){ // edit alertDialog
var editItem = AlertDialog(
title: Text('Edit'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
decoration: InputDecoration(
hintText: 'Edit Item',
),
controller: addeditem,
),
TextButton(
child: Text('Done'),
onPressed: (){
_editItem();
Navigator.of(context).pop();
}
)
],
),
);
return showDialog( //like that
context: context,
builder: (BuildContext context){
return editItem;
}
);
}
Also your way is right,you can use poping for close previous pop up.

Flutter : PopUp Form value showing null

Iam new to flutter.
In my project I need to show a popup when i load my page. So i used WidgetsBindingin initstate().
My code is working fine for showing popup on pageload, but in that popup,there is a textfield to enter mobile number after submitting i need to get that phone number but it not showing the value. While compiling it showing null value.
#override
void initState() {
super.initState();
// _fetchSessionAndNavigate();
WidgetsBinding.instance.addPostFrameCallback((_) async {
await showDialog<String>(
context: context,
builder: (BuildContext context) => new AlertDialog(
content: Stack(
overflow: Overflow.visible,
children: <Widget>[
Positioned(
right: -40.0,
top: -40.0,
child: InkResponse(
onTap: () {
Navigator.of(context).pop();
},
child: CircleAvatar(
child: Icon(Icons.close),
backgroundColor: Colors.red,
),
),
),
Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: EdgeInsets.all(8.0),
child: TextFormField(
keyboardType: TextInputType.number,
maxLines: 1,
obscureText: true,
autofocus: false,
decoration: new InputDecoration(
hintText: 'Enter Mobile Number',
icon: new Icon(
Icons.phone_iphone,
color: Colors.grey,
)),
validator: (value) => value.isEmpty
? 'Phone Number can\'t be empty'
: null,
onSaved: (value) => phoneNumber = value.trim();
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: RaisedButton(
child: Text("Register Your Device"),
onPressed: () {
if (_formKey.currentState.validate()) {
//_formKey.currentState.save();
Print (_phoneNumber); //NEED TO GET ENTERED VALUE HERE
}
},
),
)
],
),
),
],
),
),
);
});
}
You can remove the await keyword from in front of the function and call it like this:
showDialog({the dialog}).then((dialogResult){
setState((){
yourLocalVariable = dialogResult;
});
});

Use Navigator.push (MaterialPageRoute) instead of AlertDialog

I would like to use Navigator.push (MaterialPageRoute) instead of AlertDialog as now I think its better for my user to have a full page to post content rather than a dialog box, how would I go about editing my code to do this? Thanks in advance
appBar: AppBar(
centerTitle: true,
title: Text('hehe',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 25.0),),
actions: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 10.0),
child: IconButton(icon: Icon(Icons.comment),
onPressed: () {
showDialog(context: context,
builder: (BuildContext context){
return AlertDialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
content: Form(key: formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: EdgeInsets.all(8.0),
child: TextFormField(
initialValue: '',
onSaved: (val) => board.subject = val,
validator: (val) => val == "" ? val: null,
),
),
Padding(
padding: EdgeInsets.all(8.0),
child: RaisedButton(
color: Colors.indigo,
child: Text(
'Post',
style: TextStyle(color: Colors.white),),
onPressed: () {
handleSubmit();
Navigator.of(context).pop();
},
),
)
],
),
),
);
},
);
}
),
),
],
),
Create a StatefulWidget subclass say MyForm.
class MyForm extends StatefulWidget {
#override
_MyFormState createState() => _MyFormState();
}
class _MyFormState extends State<MyForm> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("My form")),
body: Form(
key: formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: EdgeInsets.all(8.0),
child: TextFormField(
initialValue: '',
onSaved: (val) => board.subject = val,
validator: (val) => val == "" ? val : null,
),
),
Padding(
padding: EdgeInsets.all(8.0),
child: RaisedButton(
color: Colors.indigo,
child: Text(
'Post',
style: TextStyle(color: Colors.white),
),
onPressed: () {
handleSubmit();
Navigator.of(context).pop();
},
),
)
],
),
),
);
}
}
And use it like this in your onPressed method.
onPressed: () {
Navigator.push(context, MaterialPagerRoute(builder: (context) => MyForm()));
}
So, when the button is clicked, you will be navigated to the new page which is your form currently.