Creating TextField list - flutter

I want to create a list that users want how many include TextField with initial count is two and buttons when pressed adding one more, another when clicked clearing all fields. Then, calculate standard deviation from inputs . What is the best way achieve this ? Make a custom Row widget ? With List widget or ListView.builder widget ?

children: <Widget>[
Flexible(
fit: FlexFit.tight,
flex: 5,
child: FractionallySizedBox(
widthFactor: 0.9,
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder()
),
controller: count,
),
),
),
Flexible(
fit: FlexFit.tight,
flex: 3,
child: FractionallySizedBox(
widthFactor: 0.9,
child: RaisedButton(
child: Text("Press here"),
padding: EdgeInsets.symmetric(vertical: 20),
onPressed: () {
fi = int.parse(count.text);
setState(() {});
},
),
),
),
],
),
),
fi == null
? Offstage()
: ListView.builder(
physics: NeverScrollableScrollPhysics(),
padding: EdgeInsets.all(10),
shrinkWrap: true,
itemCount: fi,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: index.toString()
),
),
);
},
),
],
),
),
),
); }}
You can do like this whenever you want to render dynamic textfield then you have to follow like above code thanks

Related

Flutter app expanding behind navigation bar

After hours of trial and error, I gave up.
Can somebody tell me why my app is expanding behind the virtual navigation buttons?
I tried swiching and inserting SafeArea, Flex, Expanded and so on but have not found which Widget is creating this behaviour.
My Code:
Widget build(BuildContext context) {
return Scaffold(
body: Column(
// direction: Axis.vertical,
children: [
Expanded(
flex: 1,
// child:Text("test text", style: TextStyle(backgroundColor: Colors.blue),)
child: Container(
// color: Colors.red,
alignment: Alignment.centerRight,
// padding: EdgeInsets.all(0),
child: TextField(
controller: _input_controller,
decoration: const InputDecoration(
focusedBorder: InputBorder.none,
border: InputBorder.none,
),
style: TextStyle(fontSize: _font_size),
textAlign: TextAlign.right,
showCursor: false,
readOnly: true,
// decoration: InputDecoration(labelText: "Enter your number"),
// keyboardType: TextInputType.number,
// inputFormatters: [
// // FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
// // FilteringTextInputFormatter.allow(RegExp(r"[.,']")),
// CardFormatter
// ], // Only numbers can be entered
)),
),
Expanded(
flex: 1,
// child:Text("test text", style: TextStyle(backgroundColor: Colors.blue),)
child: Container(
// color: Colors.red,
alignment: Alignment.centerRight,
// padding: EdgeInsets.all(0),
child: TextField(
controller: _answer_controller,
decoration: const InputDecoration(
focusedBorder: InputBorder.none,
border: InputBorder.none,
),
style: TextStyle(fontSize: _font_size),
textAlign: TextAlign.right,
showCursor: false,
readOnly: true,
// decoration: InputDecoration(labelText: "Enter your number"),
// keyboardType: TextInputType.number,
// inputFormatters: [
// // FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
// // FilteringTextInputFormatter.allow(RegExp(r"[.,']")),
// CardFormatter
// ], // Only numbers can be entered
)),
),
Expanded(
flex: 4,
// child:Text("test text", style: TextStyle(backgroundColor: Colors.green),)
child: GridView.count(
crossAxisCount: 4,
// padding: const EdgeInsets.all(0.2),
mainAxisSpacing: 0,
crossAxisSpacing: 0,
children: List.generate(
20,
(i) => Container(
child: TextButton(
onPressed: () {
print(i);
},
child: Text(i.toString()),
),
))),
)
],
),
);
} crossAxisSpacing: 0,
children: List.generate(
20,
(i) => Container(
child: TextButton(
onPressed: () {
print(i);
},
child: Text(i.toString()),
),
)),
),
)
],
),
),
),
),
);
}
The issue is your screen height doesn't cover the Full widget height. That's why the GridView is behind the screen. If you scroll down, you will get the rest of the button. You can play with childAspectRatio to reduce the height.
If you like to have everything in withing screen, you can use Stack and LayoutBuilder to measure the screen size. But it is nice to have scroll-effect for small screen but I will prefer full scroll body, In that case you can use SingleChildScrollView on body and NeverScrollableScrollPhysics() on gridView.
You can check my repo I was testing year ago.
As always, when you ask, you get the answer shortly after by yourself (with a hint from Chance)
Putting GridView inside Expanded causes this behaviour, if you put GridView inside a Container you get an assertion error, add shrinkWrap: true to the Constructor of GridView and everything works as expected:
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Expanded(flex: 1, child: Text("Text1")),
Expanded(flex: 1, child: Text("Text1")),
Container(
child: GridView.count(
crossAxisCount: 4,
mainAxisSpacing: 0,
crossAxisSpacing: 0,
shrinkWrap: true,
children: List.generate(
20,
(i) => Container(
child: TextButton(
onPressed: () {
print(i);
},
child: Text(i.toString()),
),
))),
)
],
));
}

flutter widget hides behind keyboard when it opens

I am trying to create a chat screen with text field at the bottom and whenever it is clicked the keyboard comes up and the textfield should be on top of the keyboard but my own isn't doing what it's supposed to do. I have checked other similar questions and answers on google, stackoverflow and github but it still stays the maybe because in mine am using constraints: BoxConstraints(maxHeight: 160), which might be what is causing it but i don't really know
This my code
class _ChatSectionState
extends State<ChatSectionState> {
List<File> images = List<File>();
getMultiFile() async {
await pickFileFromMobile("multi").then((value) {
if (value != null) {
value.paths.forEach((element) {
images.add(File(element));
});
// images = value.paths.map((path) => File(path)).toList();
}
});
setState(() {});
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(...,
body: Container(
height: double.infinity,
child: Stack(
children: [
Padding(
padding: EdgeInsets.only(bottom: 50),
child: Container(
child: ListView.builder(
itemCount: 10,
reverse: true,
shrinkWrap: true,
physics: ScrollPhysics(),
itemBuilder: (ctx, idx) {...
///...
),
),
),
///This is the part that hides behide the keyboard when it appears which i want to show on top
Align(
alignment: Alignment.bottomCenter,
child: Container(
decoration: BoxDecoration(
color: white,
border: Border(
top: BorderSide(
color: grey[400],
width: .7,
),
bottom: BorderSide(
color: grey[400],
width: .7,
)),
),
constraints: BoxConstraints(maxHeight: 160), //This is the box contraints
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
(images.length < 1)
? SizedBox(height: 0)
: Expanded(
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
physics: ScrollPhysics(),
padding: EdgeInsets.symmetric(
vertical: 7, horizontal: 10),
itemCount: images.length,
itemBuilder: (ctx, idx) {
return Container(
///... This is to show a image from file width a height of 100
);
},
),
),
Container(
decoration: BoxDecoration(
border: Border(
top: BorderSide(
color: grey[300],
width: .5,
)),
),
child: Row(children: [
Container(
margin: new EdgeInsets.symmetric(horizontal: 8.0),
child: new IconButton(
icon: new Icon(Icons.image),
onPressed: () => getMultiFile(),
color: primary,
),
),
Flexible(
child: Container(
child: TextFormField(
//controller: messageEditingController,
style: TextStyle(color: nBlack, fontSize: 15.0),
decoration: InputDecoration.collapsed(
hintText: 'Type a message',
hintStyle: TextStyle(color: grey),
),
onFieldSubmitted: (value) {},
),
),
),
Container(
margin: new EdgeInsets.symmetric(horizontal: 8.0),
child: new IconButton(
icon: new Icon(Icons.send),
onPressed: () {},
color: primary,
),
),
]),
),
],
),
),
)
],
),
),
resizeToAvoidBottomInset: false,
));
}
}
Please how can I make it work cause i have checked different pages still does give me what i want. I also tried this [answer][1]
[1]: https://stackoverflow.com/a/49715952/14650702 which worked but the animation was terrible
You can change resizeToAvoidBottomInset: ture, for scaffold.
it will shrink the whole scaffold when keyboard is opened.
I use another way. resizeToAvoidBottomInset: true and do some changes for lifting widgets top of keyboard.
bottom = MediaQuery.of(context).viewInsets.bottom;
Scaffold(
resizeToAvoidBottomInset: ture,
body: SingleChildScrollView(
reverse:true,
child: Padding(
padding: EdgeInsets.only(bottom: bottom),
child: ...
)));
if you decrease space from keyboard to last widget use MediaQuery.of(context).viewInsets.bottom/2 e.x.

Flutter add more fields in a form

I am creating a form in flutter that will be used to capture data. One area of the capture form should be able to capture more than one entry. How can I use a button to add more fields so that it is possible for a user to enter more that one entry . This is the part of the form
_Details() {
return Column(
children: <Widget>[
Container(
alignment: Alignment.center,
width: double.infinity,
color: Theme.of(context).accentColor,
padding: const EdgeInsets.all(8.0),
child: Text("Details "),
),
SizedBox(
height: 5.0,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
// crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextFormField(
controller: _bankController,
decoration: InputDecoration(
hintText: 'Name',
),
),
SizedBox(
height: 5.0,
),
TextFormField(
controller: _bankController,
decoration: InputDecoration(
hintText: 'Branch',
),
)
],
),
),
],
);
}
first make a model class like this
class TextFieldClass{
TextEditingController controller = new TextEditingController();
var hint;
TextFieldClass({this.controller,this.hint});
}
then you just have to make a listview and call a widget function whereever you want, like this
List<TextFieldClass> textFields = [];
Widget list(){
return Container(
padding:EdgeInsets.symmetric(vertical: 10),
child: ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: textFields.length,
itemBuilder: (context,index){
return Padding(
padding: EdgeInsets.symmetric(vertical: 5),
child:TextFormField(
controller: textFields[index].controller,
decoration: InputDecoration(
hintText:textFields[index].hint,
),
)
);
}),
);
}
now the last part you just have to add items in list
For example you make a add button and in add's button onTap function you will write
textFields.add(TextFieldClass(
controller: newController,
hint: 'new field'
));

How to arrange the items correctly in flutter

I try to make design of page of display comment. I need make page design is as follows: list at up and then Text Field at the bottom.So user will can see all comment and send new comment.
Something like photo:
but I have same problem with display.
This is my code:I make it like that now but now I can see list just without text field at the bottom
#override
Widget build(BuildContext context) {
return FutureBuilder<List<Flowerdata>>(
future: fetchFlowers(),
builder: (context, snapshot) {
if (!snapshot.hasData) return Center(
child: CircularProgressIndicator()
);
return ListView(
children: snapshot.data
.map((data) => Column(children: <Widget>[
GestureDetector(
onTap: ()=>{
getItemAndNavigate(data.id, context)
},
child: Row(
children: [
Container(
width: 100,
height: 100,
margin: EdgeInsets.fromLTRB(10, 0, 10, 0),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child:
Image.network(data.flowerImageURL,
width: 200, height: 100, fit: BoxFit.cover,))),
Flexible(child:
Text(data.flowerName,
style: TextStyle(fontSize: 18))
),
]),),
Divider(color: Colors.black),
],))
.toList(),
);
Container(
width: 280,
padding: EdgeInsets.all(10.0),
child: TextField(
controller: naameController,
autocorrect: true,
decoration: InputDecoration(hintText: 'Enter Your Name Here'),
)
);
},
);
}
How can I arrange the items correctly?
First, your Container widget is unreachable, you should fix it then you can wrap your widgets with Column and wrap ListView with Expanded widget after giving height to Container. It will fix your problem.
But i have some suggestions about ListView. Why you did not use ListView.separated? If you use separated method you can delete map and your Divider.
Also when i looked your design, your list items looks like a card. You can use Card widget beside of GestureDetector.
I hope this will help you, if not i will glad to help you.
Edit: Here is sample code based on your question and my answer;
Column(
children: [
Expanded(
child: ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int i) {
InkWell(
onTap: () => getItemAndNavigate(snapshot.data[i].id, context),
child: Card(
child: Row(
children: <Widget>[
Container(
width: 100,
height: 100,
margin: EdgeInsets.fromLTRB(10, 0, 10, 0),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Image.network(snapshot.data[i].flowerImageURL,
width: 200, height: 100, fit: BoxFit.cover,),
),
),
Flexible(
child: Text(
snapshot.data[i].flowerName,
style: TextStyle(fontSize: 18),
),
),
]
),
),
);
},
),
),
Container(
width: 280,
padding: EdgeInsets.all(10.0),
child: TextField(
autocorrect: true,
decoration: InputDecoration(hintText: 'Enter Your Name Here'),
),
),
],
),
You are placing the TextField in the position after returning ListView, which make it dead code. You can add it at the end of your ListView children list or place a Stack outside to place both the ListView and TextField inside.

List menu scrolling without IgnorePointer

I created a menu list with GridView. But when I scroll, it fail because scroll inside listview hold parent element to scroll like this image
My issue is gone when I try to wrap my GridView inside IgnorePointer. But if I use IgnorePointer it is not allow me to click / tap my menu item.
How the best way to fix my issue?
My code (without IgnorePointer)
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(top: 10.0, bottom: 10.0),
width: MediaQuery.of(context).size.width,
child: GridView.count(
shrinkWrap: true,
crossAxisCount: 4,
children: List.generate(
menuItems.length,
(index) {
return Column(
children: <Widget>[
InkWell(
onTap: () {
showShortToast("Menu clicked " + index.toString());
},
child: Container(
width: 70.0,
height: 70.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
border: Border.all(color: Colors.grey[300]),
),
child: Center(
child: Image.asset(menuItems[index]["image"]),
),
),
),
Expanded(
child: Text(
menuItems[index]["text"],
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 13.0,
),
),
),
],
);
},
),
),
);
}
If you want to disable the scroll in the grid view you can do as follows:
child: GridView.count(
physics: NeverScrollableScrollPhysics(), //Add physics
shrinkWrap: true,
crossAxisCount: 4,
...