I am new to flutter and I’m trying to create a counter that begins from a user input and decrement but I can’t get an integer input from text field how can I initialize a user input to be an integer then add it to an int variable
That is quite simple, I will show you an example that you can follow.
Example:
class HomePage extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return new HomePageState();
}
}
class HomePageState extends State<HomePage> {
// creating and initilizing a counter variable
int _counter = 0;
TextEditingController _controller = TextEditingController();
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new TextField(
controller: _controller,
decoration: new InputDecoration(labelText: "Enter your number"),
keyboardType: TextInputType.number,
),
FlatButton(
onPressed:(){
_counter = int.parse(_controller.text);
},
child: Text('Press Me!'),
)
],
));
}
}
At first, I created a counter and initialize it with '0' and then I created a controller which I will use for controlling the TextField. After that, I created a TextField widget and passed the _controller to it. I used the controller because I need to fetch data from the TextField so do we. We fetched data from the _controller via _controller.text which returns a string. Although we create the counter as an integer, we can't pass a string to it. So, I changed the data that we fetched from the _controller into an integer using int.parse(_controller.text) and then we passed it to the _counter variable.
Note: I had specified the keyboardType as TextInputType.number because we are dealing with numbers as you mentioned.
Related
I am building an app that generates form fields from JSON data.
the Form widget is declared in the custom_form.dart
child: Form(
key: _globalKey,
child: Column(
children: [
SizedBox(
height: 10,
),
Text("Register Form: "),
SizedBox(
height: 3,
),
for (var i = 0; i < this.widget.widgetList.length; i++)
generateWidgetFromType(this.widget.widgetList[i]),
I'm using that generateWidgetFrom Type to generate the widgets
Widget generateWidgetFromType(Mywidget mywidget) {
switch (mywidget.type) {
case "CheckBox":
return GenerateCheckBox(mywidget);
case "Input":
return CustomGeneratedWidget(mywidget,
onSaved: (value) => widget.test = value);
case "DatePicker":
return GenerateDatePicker(mywidget);
}
return Text("This type is not supported yet");
}
The TextFormField is declared in the CustomGeneratedWidget
child: TextFormField(
controller: textEditingController,
obscureText: isPasswordField(this.widget.mywidget.key),
keyboardType: customType(this.widget.mywidget.key),
decoration: InputDecoration(
labelText: this.widget.mywidget.label,
border: OutlineInputBorder()),
validator: (value) {
I want to retrieve data from TextFormField in the CustomGeneratedWidget when I click on the Add button in the custom_form.dart
One way might be to add a method called getValue() on to your CustomGeneratedWidget class:
class CustomGeneratedWidget extends Mywidget {
TextEditingController textEditingController = TextEditingController();
...
String getValue() {
return textEditingController.text;
}
...
#override
Widget build(BuildContext context) {
...
}
}
I'm guessing, based on what you're building, that you'll want to eventually get data not just from TextFormField / CustomGeneratedWidget instances, but also instances of GenerateCheckBox and GenerateDatePicker as well. With that being the case, if it were me, I would add an abstract method to Mywidget that you override in its subclasses, perhaps called getValue(). So, Mywidget might look like:
abstract class Mywidget extends Widget {
...
// this method is purposefully unimplemented, and is therefore an "abstract" method
dynamic getValue();
...
}
In your subclasses, such as CustomGeneratedWidget, you would "override" this method by redefining it / implementing it, and therefore making it "concrete":
class CustomGeneratedWidget extends Mywidget {
TextEditingController textEditingController = TextEditingController();
...
#override
String getValue() {
return textEditingController.text;
}
#override
Widget build(BuildContext context) {
return Container(
child: TextFormField(
controller: textEditingController
...
)
);
}
}
Back in custom_form.dart, in your handler for your 'Add' button, you could go through the list of created Mywidget instances and call getValue() on each.
I have a Posts screen where list of posts are displayed. I want to add a textformfield at the bottom area of each post so that users can enter their comments on particular post. As we know that we cannot create a TextEditingController for multiple textformfields.
How can I create, show and use textformfield with the each post for entering users comments?
I am sure there are multiple ways to do this, but here is one fairly simple approach.
Create a Map where the key is a TextFormField and the value is a TextEditingController.
Map<TextFormField, TextEditingController> fields = new Map<TextFormField, TextEditingController>();
Create a new controller and text field for each post and add them to the Map.
fields[text] = controller;
When you want to get the values, you can pass the text field into a method that gets the controller for that field from the Map.
Here is a very basic example of how this can work:
import 'package:flutter/material.dart';
class DynamicTextFieldsWithControllers extends StatefulWidget {
#override
State<StatefulWidget> createState() => DynamicTextFieldsWithControllersState();
}
class DynamicTextFieldsWithControllersState extends State<DynamicTextFieldsWithControllers> {
Map<TextFormField, TextEditingController> fields = new Map<TextFormField, TextEditingController>();
#override
Widget build(BuildContext context) {
List<Widget> widgets = [];
for(int i = 0; i < 5; i++) {
TextEditingController controller = new TextEditingController();
TextFormField text = TextFormField(
controller: controller,
);
fields[text] = controller;
widgets.add(Container(
margin: EdgeInsets.symmetric(horizontal: 8.0, vertical: 15.0),
child: Column(children: [
text,
FlatButton(
color: Colors.blue,
child: Text("Submit", style: TextStyle(color: Colors.white)),
onPressed: () {
getTextValue(text);
},
)
],)
));
}
return Scaffold(
body: Column(children: widgets),
);
}
getTextValue(TextFormField text) {
TextEditingController controller = fields[text];
String value = controller.text;
print(value);
return value;
}
}
I'm trying to insert an initial value to the flutter_quill flutter text editor with no success. Link to package https://pub.dev/packages/flutter_quill . From a normal TextField I would have done something like below using the controller.
class _FooState extends State<Foo> {
TextEditingController _controller;
#override
void initState() {
super.initState();
_controller = new TextEditingController(text: 'Initial value');
}
#override
Widget build(BuildContext context) {
return new Column(
children: <Widget>[
new TextField(
// The TextField is first built, the controller has some initial text,
// which the TextField shows. As the user edits, the text property of
// the controller is updated.
controller: _controller,
),
],
);
}
}
I appreciate your help.
Currently, when a user fills in a TextField the text is lost if they navigate away and then return. How can I get the text to stay in the field upon their return?
Here's the stateful widget I'm using;
class _EditPageState extends State<EditPage> {
final _formKey = GlobalKey<FormState>();
String audiotitle;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Form(
key: _formKey,
child: Container(
child: TextField(
decoration: new InputDecoration(
hintText: widget.oldaudiotitle,
),
keyboardType: TextInputType.text,
onChanged: (titleText) {
setState(() {
this.audiotitle = titleText;
});
},
),
),
),
);
}
}
What am I doing wrong here?
you have two ways :
store the Data of the text field and set the data in init method
(use sharedpreferences or any other database as per your requirements)
TextEditingController controller = TextEditingController();
#override
void initState() {
// TODO: implement initState
// retrive the Data
if(data != null) {
controller = new TextEditingController(text: data);
}
}
or if the first screen is navigating in the second Screen than just pop that screen
Navigator.pop(context);
I am trying to create a page with more than one TextField widgets in flutter. Number of textfields to display are determined at runtime. while creating those textfields a controller from the controller array is attached to each textfield.
Everything is working as expected. but doen't matter which textfield i click, i always get the callback of all the textfields in a single onChanged function.
Therefore, i am not able to detect that value of which textfield is changed.
Please refer to code for more insight.
In-Short, i just want to know how to get the instance of textfield controller which is currently active.
Could somebody please let me know what i am doing wrong.
Thanks
List<TextEditingController> _controllers = <TextEditingController>[];
int controllersAttached = -1;
#override
Widget build(BuildContext context) {
controllersAttached += 1;
for (int i = 0;i < fibProvider.quesTextList.length;i++) ...<dynamic>[
TextField(
autofocus: false,
cursorColor: const Color(0xFFD8D8D8),
maxLines: 1,
textAlign: TextAlign.center,
controller: _controllers[controllersAttached %fibProvider.numberOfBlanks],
onChanged: (String data) {
// here i can distinguish between the controllers depending upon the text
entered in them. but if there are 3 textfields and the same data is
entered in all the three then this code only returns the first
controller with the matched value.
final int index = _controllers.indexWhere(TextEditingController item) {
return data.compareTo(
item.text.toString()) == 0;
});
},
),
]
}
You can just pass i variable to onChanged callback inside collection-for:
class _MyHomePageState extends State<MyHomePage> {
final int _fields = 10;
List<TextEditingController> controllers;
#override
void initState() {
super.initState();
controllers = List.generate(_fields, (i) => TextEditingController());
}
#override
void dispose() {
controllers.forEach((c) => c.dispose());
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title)
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
for (int i = 0; i < _fields; i++)
TextField(
controller: controllers[i],
onChanged: (value) {
final controller = controllers[i];
print('Current field index is $i and new value is $value');
},
),
],
),
)
);
}
}