flutter - responsive height Form - dart

I have this simple form, with a textarea and buttons:
When I open the keyboard, I want to decrease the size of the textarea, like a responsive layout. If I close the keyboard, the textarea should fill the remaining screen space available.
desired effect: open / active keyboard
desired effect: closed/no keyboard
My intention is to make the components fill in the screen, regardless device resolution.
Can someone provide a valida example of it? I tried several implementations and I was not able to achive the desired effect.
UPDATE:
My current code for this screen:
new MaterialPageRoute(
builder: (context) {
return new Scaffold(
resizeToAvoidBottomPadding: true,
appBar: new AppBar(
title: new Text('Add new Grocery List'),
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.delete),
tooltip: 'Clear Grocery List',
onPressed: () {
this._promptRemoveGroceryBatchList();
},
),
]
),
body: new Container(
padding: const EdgeInsets.all(5.0),
child: new Form(
key: this._formGroceryBatchAdd,
child: new ListView(
children: <Widget>[
new Container(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new TextFormField(
maxLines: 10,
autofocus: true,
decoration: new InputDecoration(
labelText: 'Item List',
hintText: 'Enter a grocery list',
contentPadding: const EdgeInsets.all(16.0)
),
validator: (value) {
if (value.isEmpty) {
return 'Please enter at least one grocery item';
}
},
onSaved: (value) {
this._formBatchGroceryData = value;
},
),
new Padding(
padding: new EdgeInsets.all(8.0),
child: new Text(
'One item per line. Use ":" to specifcy the amount.\n' +
'Example:\n' +
'Potatoes:12\n' +
'Tomatoes:6',
style: new TextStyle(fontSize: 12.0, color: Colors.black54),
),
),
],
),
),
new Container(
child: new ButtonBar(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new RaisedButton(
child: new Text('Add Items'),
color: Theme.of(context).primaryColor,
textColor: Colors.white,
elevation: 4.0,
onPressed: () {
// ACTION GOES HERE
},
),
new RaisedButton(
child: new Text('Cancel'),
onPressed: () {
// ACTION GOES HERE
},
),
]
),
),
]
)
);
)
);
}
)

I'm afraid it can't be directly done using a TextField for the textarea because its size depends on the lines of text you have.
But you can simulate it by surrounding the TextField that allows unlimited lines with a Container.
This is a sample that could work for you:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Flutter Demo Home Page'),
),
body: new Column(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(),
borderRadius: BorderRadius.circular(4.0),
),
child: Padding(
padding: const EdgeInsets.only(
left: 10.0, bottom: 20.0, right: 10.0),
child: new TextField(
maxLines: null,
decoration: InputDecoration(
border: InputBorder.none,
),
),
),
),
),
),
],
),
);
}
}

Related

why my listview is not updating with setstate

here in below code i have list of widgets and used in listview iam adding widgets with list.add()in setstate also the list not updating i dont know what's happening . why my list is not updating
Here is below code
class EditorPageState extends State<EditorPage> {
List<Widget> obj = List<Widget>();
GlobalKey formkey= GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
obj.add( TextFormField(
textCapitalization: TextCapitalization.sentences,
maxLength: 50,
decoration: InputDecoration(
labelText: "TITLE",
hintText: "UR ARTICLE NAME"
),
));
obj.add(TextFormField(decoration: InputDecoration(
labelText: "Article's Propic",
hintText: "Only image Url is Accepted"
),));
return Scaffold(
appBar: AppBar(title: Text("data"),),
body: Form(
key: formkey,
child:Stack(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 50),
child: ListView(
shrinkWrap: true,
children: obj
),
),
Container(
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SizedBox(),
Container(
alignment: Alignment.bottomCenter,
height: 50,width: MediaQuery.of(context).size.width,
color: Colors.black38,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(icon: Icon(Icons.format_bold),color: Colors.white,onPressed: (){
setState(() {
obj.add(TextFormField(
style: TextStyle(fontWeight: FontWeight.bold),
decoration: InputDecoration(
labelText: "heading"
),
));
});
},),
IconButton(icon: Icon(Icons.add),
onPressed: (){
setState(() {
obj.add(TextFormField(
style: TextStyle(fontWeight: FontWeight.bold),
decoration: InputDecoration(
labelText: "Start again here"
),
));
});
}
),
IconButton(icon: Icon(Icons.add_a_photo),
onPressed: (){
}
),
IconButton(icon: Icon(Icons.delete),
onPressed: (){
},
)
],
),
),
],
),
),
],
),
),
);
}
}
the above code is of statefulwidget ad it is fullscreen dialog
thats it can i know why my list is not updated
Well you will need implement a ListViewBuilder to do this and please, split your layout creation your build method isn't readable. I make some changes in your layout to be more readable and the source code has some comments to help you get what I changed. I hope it can help and also you can adapt this code to your needs.
class EditorPageState extends State<EditorPage> {
List<Widget> obj = List<Widget>();
GlobalKey formkey= GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
obj.add( TextFormField(
textCapitalization: TextCapitalization.sentences,
maxLength: 50,
decoration: InputDecoration(
labelText: "TITLE",
hintText: "UR ARTICLE NAME"
),
));
obj.add(TextFormField(decoration: InputDecoration(
labelText: "Article's Propic",
hintText: "Only image Url is Accepted"
),));
return Scaffold(
appBar: AppBar(title: Text("data"),),
//you can use this property to easily create a bottom navigation
bottomNavigationBar: _buildBottomNavigator(), // this method return BottomNavigation layout
body: Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Form(
key: formkey,
/// here your question answer... you need implemet a listView builder
/// in every build this will create a new ListView getting itens of a especific list
child : ListView.builder(
itemCount: obj.length, // number of items in your list
//here the implementation of itemBuilder. take a look at flutter docs to see details
itemBuilder: (BuildContext context, int Itemindex){
return obj[Itemindex]; // return your widget
}),
),
),
);
}
//create your bottom navigation layout
Widget _buildBottomNavigator(){
return Container(
color: Colors.black54,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(icon: Icon(Icons.format_bold),color: Colors.white,onPressed: (){
setState(() {
obj.add(TextFormField(
style: TextStyle(fontWeight: FontWeight.bold),
decoration: InputDecoration(
labelText: "heading"
),
));
});
},),
IconButton(icon: Icon(Icons.add),
onPressed: (){
print("on pressed");
setState(() {
obj.add( TextFormField(
style: TextStyle(fontWeight: FontWeight.bold),
decoration: InputDecoration(
labelText: "Start again here"
),
));
});
}
),
IconButton(icon: Icon(Icons.add_a_photo),
onPressed: (){
}
),
IconButton(icon: Icon(Icons.delete),
onPressed: (){
},
)
],
),
);
}

How do I remove a child that's been pressed from ListView

I have a ListView in which I will dynamically add in some children of same type. Inside every children widget has a button. What I want to implement is, that, when user presses the button on a child widget, this child widget will be removed from the ListView. I can do this in C# using events, but I'm a total noob to Dart and Flutter.
Here is my ListView
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('Edit Plan'),
backgroundColor: Colors.green,
actions: <Widget>[
Builder(
builder: (context) => IconButton(
icon: Icon(Icons.add),
onPressed: () {
setState(() {
txts.add('set');
});
},
),
)
],
),
backgroundColor: Colors.white,
body: ListView(
children: txts.map((string) =>
new ListViewItem()).toList(growable: false),
),
);
}
And here is my listViewItem:
class ListViewItem extends StatelessWidget {
final Workout workout;
ListViewItem({Key key, #required this.workout})
: assert(workout != null),
super(key: key);
#override
Widget build(BuildContext context) {
// TODO: implement build
final theme = Theme.of(context);
return Padding(
padding: EdgeInsets.all(12),
child: Card(
elevation: 12,
color: Colors.green,
child: Padding(
padding: EdgeInsets.only(top: 4, bottom: 4, left: 8, right: 8),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const ListTile(
leading: Icon(Icons.album),
title: Text(
'The Enchanted Nightingale',
style: TextStyle(color: Colors.white),
),
subtitle: Text(
'Music by Julie Gable. Lyrics by Sidney Stein.',
style: TextStyle(color: Colors.white),
),
),
TextFormField(
decoration: InputDecoration(
labelText: 'Name your workout',
labelStyle: TextStyle(color: Colors.white)),
),
ButtonTheme.bar(
// make buttons use the appropriate styles for cards
child: ButtonBar(
children: <Widget>[
FlatButton(
child: const Text(
'DELETE',
style: TextStyle(color: Colors.white),
),
onPressed: () {},
),
],
),
),
],
),
)),
);
}
}
I edited your code to use a ListView.builder, you need to remove the item at index from the List (txts) you are using, your code will be as follows:
List<String> txts = List();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Edit Plan'),
backgroundColor: Colors.green,
actions: <Widget>[
Builder(
builder: (context) =>
IconButton(
icon: Icon(Icons.add),
onPressed: () {
setState(() {
txts.add('set');
});
},
),
)
],
),
backgroundColor: Colors.white,
body: new ListView.builder(
itemCount: txts.length,
itemBuilder: (BuildContext context, int index) {
return ListViewItem(
workout: workout,
onDelete: (){
setState(() {
txts.removeAt(index);
});
},
);
},
),
);
}
in addition to that you need to add an ondelete callback in the ListViewItem, the code in the ListViewItem class will be as follows:
class ListViewItem extends StatelessWidget {
final Workout workout;
final VoidCallback onDelete;
ListViewItem({Key key, #required this.workout, this.onDelete})
: assert(workout != null),
super(key: key);
#override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Padding(
padding: EdgeInsets.all(12),
child: Card(
elevation: 12,
color: Colors.green,
child: Padding(
padding: EdgeInsets.only(top: 4, bottom: 4, left: 8, right: 8),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const ListTile(
leading: Icon(Icons.album),
title: Text(
'The Enchanted Nightingale',
style: TextStyle(color: Colors.white),
),
subtitle: Text(
'Music by Julie Gable. Lyrics by Sidney Stein.',
style: TextStyle(color: Colors.white),
),
),
TextFormField(
decoration: InputDecoration(
labelText: 'Name your workout',
labelStyle: TextStyle(color: Colors.white)),
),
ButtonTheme.bar(
// make buttons use the appropriate styles for cards
child: ButtonBar(
children: <Widget>[
FlatButton(
child: const Text(
'DELETE',
style: TextStyle(color: Colors.white),
),
onPressed: () =>onDelete(),
),
],
),
),
],
),
)),
);
}
}

TextFormField is not working properly, its blinking continuously

TextFormField is not working properly, its blinking continuously and it doesn't allow me to write anything, as I tap on the TextFormField my keyboard appears for a second and disappear instantly. I am confused what wrong I have done with my code, I've matched my code with previous working code, but still getting this behaviour .
Here is my code.
class ComingSoonState extends State<ComingSoon> {
String language;
TextEditingController _textEdititingController ;
#override
void initState() {
_textEdititingController = new TextEditingController(); //Initialised TextEditingController
super.initState();
}
#override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final Size size = MediaQuery.of(context).size;
final formData = new Form(
key: widget._formKey,
child: new Container(
padding: const EdgeInsets.only(
left: 35.0,
right: 35.0),
child: new Column(
children: <Widget>[
new Theme(
data: theme.copyWith(primaryColor: Colors.black54),
child: new TextFormField(
controller: _textEdititingController, //ADDED CONTROLLER HERE
style: const TextStyle(color: Colors.black54),
decoration: new InputDecoration(
labelText: 'Amount',
labelStyle: const TextStyle(color: Colors.black54)
),
// validator: this._validateEmail,
validator: (val) {
return val.isEmpty
? "Please enter amount"
: null;
},
onSaved: (String value) {
// this._data.email = value;
this.language = value;
}
),
),
],
),
),
);
return Scaffold(
appBar: new AppBar(
leading: null,
title: const Text('Send Money', style: const TextStyle(
color: Colors.white
),
),
),
body: new Container(
color: Colors.grey[300],
child: new ListView(
children: <Widget>[
new Container(
child: new Column(
children: <Widget>[
new Container(
height: 60.0 ,
padding: const EdgeInsets.all(5.0),
child: new Card(
child: new Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: new Text("Available balance in wallet", style:
new TextStyle(color: Colors.black54,
fontSize: 16.0
),),
),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: new Text("123 KSH", style:
new TextStyle(color: Colors.blueAccent,
fontSize: 16.0
),),
),
],
),
),
) ,
new Container(
//height: 300.0,
padding: const EdgeInsets.all(5.0),
child: new Card(
child: new Container(
child: new Center(
child: new Column(
children: <Widget>[
formData
],
),
),
),
),
)
],
)
),
],
),
),
);
}
}
I added a floating action button that presents a dialog that will show what you entered into the TextField (using the controller). I'm not sure what form key you were passing in before but making the GlobalKey instance a member variable eliminates the keyboard present/dismiss issue.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String language;
TextEditingController _textEditingController;
final _formKey = GlobalKey<FormState>();
#override
void initState() {
_textEditingController =
TextEditingController(); //Initialised TextEditingController
super.initState();
}
#override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final Size size = MediaQuery.of(context).size;
final formData = Form(
key: _formKey,
child: Container(
padding: const EdgeInsets.only(left: 35.0, right: 35.0),
child: Column(
children: <Widget>[
Theme(
data: theme.copyWith(primaryColor: Colors.black54),
child: TextFormField(
controller: _textEditingController,
//ADDED CONTROLLER HERE
style: const TextStyle(color: Colors.black54),
decoration: InputDecoration(
labelText: 'Amount',
labelStyle: const TextStyle(color: Colors.black54)),
// validator: this._validateEmail,
validator: (val) {
return val.isEmpty ? "Please enter amount" : null;
},
onSaved: (String value) {
// this._data.email = value;
language = value;
}),
),
],
),
),
);
return Scaffold(
appBar: AppBar(
leading: null,
title: const Text(
'Send Money',
style: const TextStyle(color: Colors.white),
),
),
body: Container(
color: Colors.grey[300],
child: ListView(
children: <Widget>[
Container(
child: Column(
children: <Widget>[
Container(
height: 60.0,
padding: const EdgeInsets.all(5.0),
child: Card(
child: Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
"Available balance in wallet",
style: TextStyle(
color: Colors.black54, fontSize: 16.0),
),
),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
"123 KSH",
style: TextStyle(
color: Colors.blueAccent, fontSize: 16.0),
),
),
],
),
),
),
Container(
//height: 300.0,
padding: const EdgeInsets.all(5.0),
child: Card(
child: Container(
child: Center(
child: Column(
children: <Widget>[formData],
),
),
),
),
)
],
)),
],
),
),
floatingActionButton: FloatingActionButton(
// When the user presses the button, show an alert dialog with the
// text the user has typed into our text field.
onPressed: () {
return showDialog(
context: context,
builder: (context) {
return AlertDialog(
// Retrieve the text the user has typed in using our
// TextEditingController
content: Text(_textEditingController.text),
);
},
);
},
tooltip: 'Show me the value!',
child: Icon(Icons.text_fields),
),
);
}
}

When I select a Textfield the keyboard moves over it

When i select a Textfield, the keyboard is going to be shown but the keyboard hide my selected TextField. Does someone have a solution?
Scaffold(
resizeToAvoidBottomInset: true,
body: SingleChildScrollView(
child: Container(
child: Column(
children: <Widget>[
TextFormField(
decoration: InputDecoration(
labelText: 'Enter Text',
),
),TextFormField(
decoration: InputDecoration(
labelText: 'Enter Text',
),
),TextFormField(
decoration: InputDecoration(
labelText: 'Enter Text',
),
),TextFormField(
decoration: InputDecoration(
labelText: 'Enter Text',
),
),TextFormField(
decoration: InputDecoration(
labelText: 'Enter Text',
),
),TextFormField(
decoration: InputDecoration(
labelText: 'Enter Text',
),
),TextFormField(
decoration: InputDecoration(
labelText: 'Enter Text',
),
),
TextFormField(
decoration: InputDecoration(
labelText: 'Enter Text',
),
)
],
),
),
)
);
// resizeToAvoidBottomPadding: false isDeprecated
use resizeToAvoidBottomInset: true.
Compose an animation and move your TextField container up when a TextField gets focus.
For learning about composing animations refer to:
Composing Animations and Chaining Animations in Dart's Flutter Framework
Use Flutter's FocusNode to detect the focus on a TextField
Edit:
Here I've written an example that does exactly what you want:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Animation Demo',
theme: new ThemeData(
primaryColor: new Color(0xFFFF0000),
),
home: new FormDemo(),
);
}
}
class FormDemo extends StatefulWidget {
#override
_FormDemoState createState() => _FormDemoState();
}
class _FormDemoState extends State<FormDemo> with SingleTickerProviderStateMixin {
AnimationController _controller;
Animation _animation;
FocusNode _focusNode = FocusNode();
#override
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: Duration(milliseconds: 300));
_animation = Tween(begin: 300.0, end: 50.0).animate(_controller)
..addListener(() {
setState(() {});
});
_focusNode.addListener(() {
if (_focusNode.hasFocus) {
_controller.forward();
} else {
_controller.reverse();
}
});
}
#override
void dispose() {
_controller.dispose();
_focusNode.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false, // this avoids the overflow error
appBar: AppBar(
title: Text('TextField Animation Demo'),
),
body: new InkWell( // to dismiss the keyboard when the user tabs out of the TextField
splashColor: Colors.transparent,
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Container(
padding: const EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
SizedBox(height: _animation.value),
TextFormField(
decoration: InputDecoration(
labelText: 'I move!',
),
focusNode: _focusNode,
)
],
),
),
),
);
}
}
Just cut and paste your body code in this -
SingleChildScrollView(
child: Stack(
children: <Widget>[
// your body code
],
),
),
A pretty short way to realize this is by simply using a MediaQuery for getting the bottom view insets. This would look as follows:
...
return Column(
children: <Widget>[
TextField(
decoration: InputDecoration.collapsed(hintText: "Start typing ..."),
controller: _chatController,
),
SizedBox(
height: MediaQuery.of(context).viewInsets.bottom,
),
],
);
...
Hope it helps!
In my case I had to combine answer given by #Javid Noutash which uses AnimationController along with scrollPadding property of TextFormField.
code:
Add this line in build method
double bottomInsets = MediaQuery.of(context).viewInsets.bottom;
Add scrollPadding property
return ListView(
children:[
...widgets,
Container(
margin:EdgeInsets.only(
top:1.0,
left:1.0,
right:1.0,
bottom:_focusNode.hasFocus && bottomInsets != 0?
_animation.value : 1.0),
child:TextFormField(
decoration: InputDecoration(
labelText: 'I move!',
),
focusNode: _focusNode,
scrollPadding: EdgeInsets.only(bottom:bottomInsets + 40.0),
),
),
]
);
Note: Combine this code with #Javid Noutash's code
I had the same problem where the parent widget is Material and the other widgets are inside a ListView. The problem was fixed when I changed the parent widget to Scaffold without any extra code and the TextField, TextFormField in my case, is being showed above the Keyboard automatically. So, if you encountered this problem just make sure to have Scaffold as the main widget.
The most simple way is to just wrap it with
SingleChildScrollView( ... )
When the textfield is on the page bottom and the keyboard appears, the textfield is automatically scrolled up. Then the text may be entered right above the keyboard.
My way here
Scaffold(
resizeToAvoidBottomInset: false,
resizeToAvoidBottomPadding: false,
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('images/Bg img.png'), fit: BoxFit.fill)),
child: Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: CustomScrollView(
slivers: [
SliverFillRemaining(
hasScrollBody: false,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
.............
This template has some advantages:
Move content up when the keyboard appears
Column using spaceBetween inside a scroll view
Background is sticked phone scren and never change event the keyboard ups
Wrap your widget into Padding and set padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
<activity
android:name="..ActivityName"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"/>
only for android
if you use FlutterFragment add configChanges and windowSoftInputMode for the Activity.
another way
add your TextField to a ListView
ListView(
children: <Widget>[
TextField(),
TextField(),
]
)
The above does not work if you have a CustomScrollview in a NestedScrollView.
First, you need to give the TextField a focusNode.
TextField(focusNode:_focusNode(),
...);
Use NestedScrollViewState to get access to the innerScrollController of the NestedScrollView. You can view the example here on how to get the innerScrollController. Declare a globalKey and assign it to NestedScrollView.
body: NestedScrollView(
key: globalKey,
...)
Setup the focusNode Listener to listen for when the textfield has been activated and animate the innerScrollController accordingly.
void initState() {
super.initState();
_focusNode.addListener(() {
if (_focusNode.hasFocus) {
double innerOffSet = globalKey.currentState.innerController.offset;
if(innerOffSet < 100)
globalKey.currentState.innerController.jumpTo(innerOffSet+100);
}
});
}
var _contentController;
void _settingModalBottomSheet(BuildContext context, String initialText) {
_contentController = new TextEditingController(text: initialText);
showModalBottomSheet(
context: context,
isDismissible: true,
builder: (BuildContext bc) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
height: 40,
margin: EdgeInsets.only(left: 4, right: 4, bottom: 8),
decoration: BoxDecoration(
color: AppColor.bgTextFieldComment,
borderRadius: BorderRadius.circular(16),
),
child: Row(
children: <Widget>[
Expanded(
child: Padding(
padding: EdgeInsets.only(left: 24),
child: TextField(
focusNode: _contentFocusNode,
autofocus: true,
controller: _contentController,
decoration: InputDecoration(
hintText: 'Enter Content',
border: InputBorder.none,
fillColor: AppColor.bgTextFieldComment,
),
keyboardType: TextInputType.multiline,
maxLines: null,
style: TextStyle(
color: Colors.black87,
fontSize: 16,
fontStyle: FontStyle.normal,
),
)),
),
InkWell(
child: Padding(
padding: EdgeInsets.only(left: 4, right: 4),
child: Icon(
Icons.send,
color: Colors.blue,
),
),
onTap: () {
// do ON TAP
},
),
],
),
),
SizedBox(
height: MediaQuery.of(bc).viewInsets.bottom,
),
],
);
},).then((value) {
print('Exit Modal');
});
print('request focus');
_contentFocusNode.requestFocus();
}
Instead of TextField, use TextFormField and wrap the widget with a list of TextFormField to Form:
Form(
child: Column(
children: <Widget> [
TextFormField(),
TextFormField(),
...
TextFormField(),
]
)
)
you can easily try to use Flexible widget just wrap your widget with it
Flexible(
child: Image(
image :
AssetImage('assets/logo.png'),
),
),
I had a very complex widget with Stack, Column and Single ChildChildScrollView, and I fixed it by adding a padding to the SCSV like this:
child: Stack(
children: [
Padding(
padding: const EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: SingleChildScrollView(
child: Column(
children: [... a lot of children here, one of them is a TextField],
),
),
),
// a widget at the bottom of the stack that shows despite the size of the scrollable column
],
),
It's very easy in my case check out code
Column(
children: [
Expanded(
child:// Top View,
),
postSend // edittext. and button
],
)

checkbox can not see from the interface flutter

1[This is how my page works. I want to get checkbox ticked and get the post paid number then can click the continue button. In my code checkbox is in between text and text form field Why i can not see my check box here and this is my code.]
new Container(
padding: const EdgeInsets.all(40.0),
child: new Form(
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Text(
"Are you a post paid customer",
style: new TextStyle(
color: Colors.blue,
fontSize: 25.0,
),
),
new Checkbox(
activeColor: Colors.blue,
value: _isChecked,
onChanged: (bool val){
onChanged(val);}
),
new TextFormField(
decoration: new InputDecoration(
labelText: "Post Paid Number",
),
obscureText: true,
keyboardType: TextInputType.text,
),
new Padding(
padding: const EdgeInsets.only(top: 60.0),
),
new MaterialButton(
height: 50.0,
minWidth: 150.0,
color: Colors.blue,
splashColor: Colors.blue,
textColor: Colors.white,
child: new Text("Continue"),
onPressed: () {
Navigator.push(
context,
new MaterialPageRoute(builder: (context) => new RegPage()),
);
},
),
Recreated your code and got it working.
You need to change _isChecked in Checkbox's onChanged like:
onChanged: (val) {
setState(() {
_isChecked = !_isChecked;
});
}),
Make sure to do it in setState or the change wont be reflected on UI.
My Code:
import 'package:flutter/material.dart';
import 'package:so_demo/sample_page.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
MyHomePageState createState() {
return new MyHomePageState();
}
}
class MyHomePageState extends State<MyHomePage> {
bool _isChecked = false;
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('SO HELP'),
),
body: new Container(
padding: const EdgeInsets.all(40.0),
child: new Form(
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Text(
"Are you a post paid customer",
style: new TextStyle(
color: Colors.blue,
fontSize: 25.0,
),
),
new Checkbox(
activeColor: Colors.blue,
value: _isChecked,
onChanged: (val) {
setState(() {
_isChecked = !_isChecked;
});
}),
new TextFormField(
decoration: new InputDecoration(
labelText: "Post Paid Number",
),
obscureText: true,
keyboardType: TextInputType.text,
),
new Padding(
padding: const EdgeInsets.only(top: 60.0),
),
new MaterialButton(
height: 50.0,
minWidth: 150.0,
color: Colors.blue,
splashColor: Colors.blue,
textColor: Colors.white,
child: new Text("Continue"),
onPressed: () {
Navigator.of(context).push(new MaterialPageRoute(builder: (context) => new RegPage());
},
),
]),
),
),
);
}
}

Resources