Flutter add more fields in a form - flutter

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'
));

Related

How to select specific radio button and get its value in ListView.builder Flutter

I would like to create a list of data that is called JSON with radio button. However, when I select any of the radio buttons it is selecting each and every radio button rather than selecting one. And, how can I get the selected radio button's value when I click on the button?
I am new to flutter. Is it any solution can solve these type of problems?
Here is my code
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Container(
height: 270,
color: Colors.white,
child: CustomScrollView(
slivers: [
SliverList(
delegate: SliverChildBuilderDelegate(
(context, i) {
return Column(
children: <Widget>[
Container(
width: 450,
padding: EdgeInsets.all(7.0),
margin: EdgeInsets.only(right: 8.0, left: 8.0, top: 10.0),
decoration: BoxDecoration(
border: Border.all(color: const Color(0xffededed)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget> [
Text(modelOptions[i].optionName.toString(),
style: TextStyle(
fontSize: 18,
color: Colors.amber,
),
),
],
),
),
Container(
margin: EdgeInsets.only(left: 8.0, right: 8.0),
padding: EdgeInsets.all(7.0),
decoration: BoxDecoration(
border:
Border.all(color: const Color(0xffededed)),
),
child: ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: modelOptions[i].modelOptionValues.length,
itemBuilder: (context, j) {
return
Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Radio(
groupValue: selectedRadio,
value: modelOptions[i].modelOptionValues[j].optionValueID,
activeColor: Colors.orangeAccent,
onChanged:(value) {
setState(() {
value = modelOptions[i].modelOptionValues[j].optionValueID.toString();
selectedRadio = value;
print("check radio: ${selectedRadio}");
showToastMessage('${selectedRadio} is selected'); //get the selected radio button's value.
});
}),
});
}),
Text(
modelOptions[i].modelOptionValues[j].valueName,
style: TextStyle(
color: Colors.black, fontSize: 16,
),),
],
);
}))
],
);
},
childCount: modelOptions.length,
),
),
],
)),
],
));
}
Radio(
groupValue: selectedRadio,
activeColor: Colors.orangeAccent,
onChanged: (val) {
setState(() {
selectedRadio = val;
showToastMessage(
"' the value ?? ' is selected"); //get the selected radio button's value.
});
}),
You're using one source of truth for the Radio's value selectedRadio. You should be updating the value for an index. Furthermore you're passing the value to the groupValue parameter instead of the value parameter. groupValue is how you... toggle the group.

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 TextFormField TextAlign.center Doesn't Make Input Centered

I am facing a little problem with Flutter UI which I'm not sure what cause it.
Here's my snippet:
class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
String fetchedData = 'doubleleng';
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
height: 40.0,
padding: const EdgeInsets.only(bottom: 8.0),
margin: const EdgeInsets.symmetric(horizontal: 40.0),
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
physics: NeverScrollableScrollPhysics(),
itemCount: fetchedData.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 4.0,
),
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.06,
child: TextFormField(
style: TextStyle(
fontSize: 20.0,
),
keyboardType: TextInputType.number,
inputFormatters: [
LengthLimitingTextInputFormatter(1),
],
textAlign: TextAlign.center,
),
),
);
},
),
),
Container(
child: RaisedButton(
onPressed: () {},
),
),
],
),
),
);
}
}
So I want to build a dynamic TextFormField based on the length of the fetchedData so I use ListView.builder. I fill the textAlign property with TextAlign.center but doesn't get exactly what I want.
Here's the SS:
Here's the SS of the weird part (not exactly centered):
It's not just '5' but all
I don't know if a problem with RepaintBoundary or font itself, but
I tried a few things and see the only solution is to use InputDecoration with Padding in your TextFormField/TextField:
TextFormField(
// your params
decoration: new InputDecoration(contentPadding: const EdgeInsets.only(left: 3.0))
)

Creating TextField list

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

How to solve ListView.builder bottom overflow issue?

I'm having the same issue that is outlined here. I've tried all of the solutions provided and I'm still getting an error "RenderFlex overflowed by x pixels on the bottom". I don't have any widgets underneath the custom ListView Builder. I'm really at a loss here.
Widget build(BuildContext context) {
return new Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new GradientAppBar("Twitter"),
new Container(
child: Flexible(
child: Column(
children: <Widget>[
Container(
padding: const EdgeInsets.only(top: 10.0, left: 10.0),
child: UserInfoHeader(userinfo)
),
PagewiseListView(
shrinkWrap: true,
scrollDirection: Axis.vertical,
physics: const AlwaysScrollableScrollPhysics(),
pageSize: 200,
itemBuilder: (context, TwitterCardContent entry, _) {
return TwitterCard(entry);
},
pageFuture: (pageIndex) {
return getStatuses(userinfo.screenName);
},
)
],
),
),
),
],
);
}
And here is the contents of each List item.
Widget build(BuildContext context) {
return new Card(
//elevation: 8.0,
margin: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
child: Container(
decoration: new BoxDecoration(
color: Colors.white,
borderRadius: new BorderRadius.circular(25.0)
),
child: ListTile(
contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0),
leading: Container(
padding: EdgeInsets.only(right: 12.0),
decoration: new BoxDecoration(
border: new Border(
right: new BorderSide(width: 1.0, color: Colors.white54)
)
),
child: notchecked,
),
title: Text(
statusCard.timeStampString,
style: Theme.TextStyles.buttonText,
),
subtitle: Text(
statusCard.text,
style: Theme.TextStyles.contentCardText,
),
trailing: delete,
),
),
);
}
Column widget doesn't scroll and you have that widget as your parent widget and PageListView as a child inside it.
Instead, replace your parent Column widget with ListView that should resolve renderflow exception.
Wrap your listview builder with expanded widget.
just to add an example to Dave's answer
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: 5,
itemBuilder: (context, index) {
return Container();
}
Problem is that your ListView is inside a Column which has fixed height and can't be scroll whereas listview scrolls. I am not sure but changing Column a listview itself or using Expanded/Flexible with Column could workOut.