Flutter Can we use ontap and onchanged property simultaneously on the single TextField? - flutter

return TextField(
// something
onTap: () {
// something something
},
onChanged: (value) {
// some if else nesteing
},
)
This is my code I want to know if we can use onTap and onChange on the same TextField.

The short answer is Yes. According to the documentation,
onChanged → ValueChanged<String>?
Called when the user initiates a change to the TextField's value: when they have inserted or deleted text. [...]
onTap → GestureTapCallback?
Called for each distinct tap except for every second tap of a double tap. [...]
They both perform completely different functions on a TextField widget.
https://api.flutter.dev/flutter/material/TextField-class.html
Updated to reflect necessity from the comment section
If you want to do something after the user is done typing, I would recommend using a delay / Debouncer. Like https://gist.github.com/venkatd/7125882a8e86d80000ea4c2da2c2a8ad
final _debouncer = Debouncer(delay: const Duration(seconds: 1));
TextField(
onChanged: (_value) {
_debouncer(() {
setState(() {
print(_value);
});
});
},
);

Related

How get more than 2 inputs from user and perform calculation and display the result in flutter application?

How to get more than 2 inputs from user and perform calculation and display the result in flutter application without using any library.
I wanna create a calculator without using any library, and want to do calculations like multiply, add subtract, division 2+6?/3-1 like this. I know how to do calculation for 2 digits but don't know how to do for more inputs. Should i use regex for this??if yes then how.
God to know:
You need TextFormField. In order to show results of the calculations to the client immediately, you should use setState method on TextFormField property onChanged.
TextEditingController _controllerFrom = TextEditingController();
String? valueFrom;
Example:
TextFormField(
onTap: () {},
controller: _controllerFrom ,
onChanged: (String value) {
if (value.isNotEmpty) {
setState(() {
valueFrom = value;
});
}
}
Also, you must dispose this controller when leaving this page on this way:
void dispose() {
// clean up the controller when the widget is disposed
_controllerFrom.dispose();
super.dispose();}

How to write data in firebase cloud firestore with data type using flutter

When saving data to the Firebase database I want every data to be saved according to its data type. But my all data is stored in String. How can I do it in flutter... like Amount will be int, Through will be String
[
here is my function
sandDataToDB() async {
CollectionReference _collectionReferance =
FirebaseFirestore.instance.collection("Use-of-fund");
return _collectionReferance
.doc()
.set({
"Details of Sector": _DetailsofSectorController.text,
"Through": _ThroughController.text,
"Amount": _AmountController.text,
"Date": _DateController.text,
})
.then((value) => dialog())
.catchError((error) => Fluttertoast.showToast(msg: "something wrong"));
}
here is all code
customAdminTextField(
"Details of Sector", _DetailsofSectorController),
customAdminTextField("Through", _ThroughController),
customAdminTextField("Amount", _AmountController),
customAdminTextField("Date", _DateController),
const SizedBox(
height: 10,
),
customSubmitButton("Submit ", () {
sandDataToDB();
})
You have to parse your data. An example for an integer:
...
"Amount": int.parse(_AmountController.text),
...
Here you can find the supported data types.
According to your question, you might be using the controller in TextFormField, you can get the value of the TextFormField.
This widget covers a TextField widget in a FormField for convenience.
It is not necessary to have a Form ancestor. The Form merely simplifies the process of saving, resetting, or validating numerous fields at the same time. To use without a Form, supply a GlobalKey to the constructor and save or reset the form field with GlobalKey.currentState.
TextEditingController.text defines the initialValue when a controller is defined. A controller should be given if this FormField is part of a scrolling container that generates its children lazily, such as a ListView or a CustomScrollView.
A stateful widget ancestor of the scrolling container should handle the controller's lifetime.
Example code:
TextFormField(
decoration: const InputDecoration(
icon: Icon(Icons.person),
hintText: 'What do people call you?',
labelText: 'Name *',
),
onSaved: (String? value) {
// This optional block of code can be used to run
// code when the user saves the form.
},
validator: (String? value) {
return (value != null && value.contains('#')) ? 'Do not use the # char.' : null;
},
)
You can also use the onSubmitted parameter in TextFormField. Like: onSubmitted: (String value)
Additionally, you can use something like this in the following code:
_formKey.currentState.save(); calls the onSaved() on each textFormField item, which gives all the fields a value and allows you to utilize them as needed.

Flutter. How to correctly update state of nested widgets?

I'm new in flutter and I'm trying to implement something like radio group with custom buttons in Android. For this I created StatefulWidget, which hold list of selectable buttons. For every button I was set press listener where I do something like this:
setState(() {
buttons.forEach((button) => button.isSelected = false);
buttons[selectedButtonIndex].isSelected = true;
});
And then my CustomButtonWidget changes color depending on the parameter isSelected .
All this works well. However, I have an additional requirement. I need my RadioGroupWidget to return the selected button type. For this I created a callback :
final ValueChanged<ButtonType> onChanged;
And now my button press listener looking like this:
onTap: () {
setState(() {
buttons.forEach((button) => button.isSelected = false);
buttons[selectedButtonIndex].isSelected = true;
});
onChanged(buttons[selectedButtonIndex].type);
}
Next I get this type of button in my other widget which is using RadioGroupWidget:
CustomRadioGroup(
onChanged: (value) {
setState(() {
buttonType= value;
});
}),
)
As you can see I call again setState. This is what leads to the problem. But I need to do this, because I need to update the state of another widget (for example let's call it InfoWidget) depending on the selected button.
After all these manipulations, the state of the InfoWidget is updated correctly, but the state of the selected button in the RadioGroupWidget does not change. I tried to debug this and I see that at first the parameter isSelected is set to true for the desired button, but after the state of the button I selected is not updated, because its parameter isSelected becomes false. And I don't understand why this is happening.
Please help, I am completely confused.

Flutter dropdownButton setState on change not updating dropdown text after selection to show selected item

I created a dropdownButton to allow users to select from a dropdown list which will be populated from an API. For now I am populating using a list I created.
Currently the button is displaying the items from my list but after a selection has been made the list doesnt show the selected item and still shows the hint text. What I would like to happen is after a selection has been made then the dropdownButton shows the item that was selected instead of the hint text.
in the onChanged method I added a setState in hopes of updating the _selectedValue variable to the value that was selected and displaying it in the dropdownButton.
I also added a print statement in my setState method and that does trigger and show me the value within the value variable.
Here is my code.
List<DropdownMenuItem<int>> listItems = [DropdownMenuItem(child: Text("2016"), value: 2016,), DropdownMenuItem(child: Text("2021"), value: 2021,)];
int _selectedValue;
body: DropdownButton(
value: _selectedValue,
items: listItems,
hint: Text("Select Year"),
onChanged: (int value){
setState(() {
_selectedValue = value;
print(value);
});
},
),
Your code is fine, but the problem is maybe you are initializing the _selectedValue inside the build() method. So that whenever you call set state the widget rebuilds and initialize again with the default value.
int _selectedValue;
#override
Widget build(BuildContext context) {
return DropdownButton(
value: _selectedValue,
items: listItems,
hint: Text("Select Year"),
onChanged: (int value){
setState(() {
_selectedValue = value;
print(value);
});
},
),
In case anyone else is having this issue, I had the same issue and it was driving me nuts and I was using setState() appropriately etc., It was 100% where I was defining the "initialValue" property.
I was defining it right inside the build method. That did not work, even though I had the same setup in a sister module and it indeed did work. Not sure why that is.
Once I changed the definition of that variable to the state class, it worked like a charm. Hope it saves some, some cycles.

Flutter - TextFormField, onChanged doesn't appear to be updating value

I'm having an issue with the use of a TextFormField in Flutter.
The method called in the initial value returns either null or a String depending on whether an add or edit screen is being used respectively.
If it is an edit screen I'd like the String to be the initial value, and the _itemName to be the initial value if it is not changed, or the new onChanged value if it is.
Below shows two of many attempts that I've made that have presented different problems.
In this case if the user does not edit the text the _itemName ends up being null or a zero length string (I can't remember exactly which one it is):
TextFormField(
initialValue: controller.initialNameValue(),
onChanged: (val) {
setState(() => _itemName = val);
}),
In this case the onChanged method does not update the _itemName and it remains at its initial value:
TextFormField(
initialValue: _itemName = controller.initialNameValue(),
onChanged: (val) {
setState(() => _itemName = val);
}),
The _itemName is then used in an add or edit method where it is passed as a parameter into a setter for a class.
How would I go about ensuring the _itemName remains as its initial value until it's changed, and then when it is changed it updates to the new value? Thanks
After some trial and error I've realised the way of overcoming this problem seems to be to introduce:
#override
void initState() {
super.initState();
_itemName = controller.initialNameValue();
}
And then change the TextFormField to:
TextFormField(
onChanged: (val) {
setState(() => _itemName = val);
},
initialValue: controller.initialNameValue(),
);
The main reason for not introducing a separate controller here was due to the fact I had multiple form fields within the widget I was building, and this created further confusion.
The above approach appears to have solved the issues that I faced, although I understand it may not be the cleanest approach to this.