Persist Data in TextFormFields between pages - flutter

I am new-ish to flutter and I have come across a problem and I would really appreciate your help.
I have two separate forms on two different screens. Clicking the "Next" button on the first page validates the form and pushes to the second page using Navigator.push(). And all works fine until I come back to the first page using the arrow on the top left corner in the app bar which is automatically created. The data inside the TextFormFields on the first page is still filled out which is good but when I click next (which validates and pushes to the second page using Navigator.push) and go to the second page all the data inside the TextFormFields has disappeared.
My intention is to have the user data entered in the TextFormFields of both forms persistent after Navigating back and forth through different screens.
I have already looked at this stackoverflow page but the solution there did not fix my issue.
I looked into shared_preferences but the people on the Flutter discord suggested not to use it.
Here is the code:
First Page
Second Page
(I used PasteUbuntu for the code as it was a bit too long so I didn't want to copy it in this post)
This is the definition for my formField() function:
class formField extends StatelessWidget {
Function validator;
Function onSaved;
String fieldTitle;
String hintText;
TextEditingController textController;
TextInputType keyboardStyle;
formField(
{this.onSaved,
this.validator,
this.fieldTitle,
this.hintText,
this.textController,
this.keyboardStyle});
#override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
RichText(
textAlign: TextAlign.left,
text: TextSpan(
text: fieldTitle,
style: GoogleFonts.questrial(
fontSize: 16,
color: Colors.black,
fontWeight: FontWeight.w500,
)),
),
SizedBox(height: 10),
Container(
width: 335,
height: 50,
child: Material(
elevation: 5.0,
borderRadius: BorderRadius.circular(10.0),
child: TextFormField(
validator: validator,
onSaved: onSaved,
textAlignVertical: TextAlignVertical.bottom,
textCapitalization: TextCapitalization.sentences,
keyboardType: keyboardStyle,
controller: textController,
decoration: InputDecoration(
filled: true,
fillColor: Color(0xFFF0F0F0),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(color: Color(0xFFE8E8E8))),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Color(0xFFE8E8E8)),
borderRadius: BorderRadius.circular(8.0),
),
hintText: hintText,
hintStyle:
GoogleFonts.inter(color: Color(0xFFBDBDBD), fontSize: 16),
),
style: GoogleFonts.inter(color: Colors.black, fontSize: 16),
),
),
),
],
);
}
}

Related

Flutter TextFormField focus

So I was coding the search bar and I used the TextFormField widget but I have a problem with this. I have two screens and the widget is in both screens. On the first screen when you tap the TextFormField it reroutes you to the second screen and there I have set autofocus to true. The only problem is that once you done searching for accounts and try to route back to the previous screen the TextFormField autofocuses again and I do not want it like that.
And here's my code.
\\\ appbar
title: Padding (
padding: const EdgeInsets.only(left: 5.0, right: 5.0),
child: TextFormField(
autofocus: false,
cursorColor: Colors.purple,
onTap: () {
FocusScope.of(context).unfocus();
TextEditingController().clear();
Get.to(() => const SearchPage());
},
decoration: InputDecoration(
suffixIcon: const Icon(
MdiIcons.databaseSearch,
),
labelText: 'Go Wild',
labelStyle: GoogleFonts.parisienne(
fontSize: 21.0,
),
enabledBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.purple),
borderRadius: BorderRadius.circular(34.0),
),
),
),
),
),
/// body of the Scaffold
I have tried different answers but none of them helps. Please help me

flutter web:I am trying to add textformfield to table column header for searching in sync fusion syncfusion_flutter_datagrid

flutter web:I am trying to add textformfield to table column header for searching the data columnwise in syncfusion_flutter_datagrid, this was workied in older version of flutter but when i upgrade to flutter 2.0.2 textformfield not accepting the inputs.
screen shot table screenshot
Library ref https://pub.dev/packages/syncfusion_flutter_datagrid
Code snippet
SfDataGrid(
columnWidthMode: ColumnWidthMode.fill,
source: _listDataGridSource,
headerRowHeight: 100,
headerCellBuilder: (BuildContext context, GridColumn column) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
column.headerText,
style: TextStyle(fontWeight: FontWeight.normal),
),
SizedBox(height: 10,),
Container(
height: 40,
child:TextFormField(
key: Key('test'+column.mappingName),
onFieldSubmitted: (value){
print("Submitted");
},
autofocus: true,
textInputAction: TextInputAction.none,
keyboardType:TextInputType.number ,
decoration: InputDecoration(
hintText: "Search here for"+column.headerText,
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.grey, width: 1.0),
),
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.grey, width: 1.0),
),
),
onChanged: (value) {
setState(() {
print('testing');
print(value);
});
}
),
)
],
);
},
Greetings from Syncfusion.
We have analyzed your reported issue. This problem is occurred due to the focus issue of the TextFormField in Flutter 2.0. We have reported this issue to framework. For further details, you can refer to the following link,
https://github.com/flutter/flutter/issues/78413
We will get back to you once we got the details from them.

TextField wrapped in a Transform.translate does not focus when clicked

This has been very confusing to me since the TextField wrapped in a SizedBox only, works perfectly; but it appears to be a simple image (it can't be tapped, nor focused) when I wrap that same piece of code in a Transform.translate widget.
Also, if I change the Transform.translate to a Positioned widget, the TextField works perfectly, but I'd like to understand why this is happening, because I am required to use Transform.translate over Positioned for this special project.
class Login extends StatelessWidget {
Login({
Key key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xfff4f6fa),
body: Stack(
children: <Widget>[
SizedBox(
width: 302.0,
height: 60.0,
child: TextField(
decoration: InputDecoration(
hintText: 'Correo electrónico *',
prefixIcon: Icon(Icons.send),
border: OutlineInputBorder(
borderSide:
BorderSide(width: 1.0, color: const Color(0xffe7e7e7)),
borderRadius: BorderRadius.circular(4.0),
),
),
style: TextStyle(
fontFamily: 'Nunito',
fontSize: 14,
color: const Color(0xff777777),
height: 1.4285714285714286,
),
textAlign: TextAlign.left,
onChanged: (String value) async {
},
onSubmitted: (String value) async {
},
),
),
// Positioned(
Transform.translate(
offset: Offset(36.0, 317.8),
// left: 36,
// top: 317.8,
child:
// Adobe XD layer: 'input:mail' (component)
SizedBox(
width: 302.0,
height: 60.0,
child: TextField(
decoration: InputDecoration(
hintText: 'Correo electrónico *',
prefixIcon: Icon(Icons.send),
border: OutlineInputBorder(
borderSide:
BorderSide(width: 1.0, color: const Color(0xffe7e7e7)),
borderRadius: BorderRadius.circular(4.0),
),
),
style: TextStyle(
fontFamily: 'Nunito',
fontSize: 14,
color: const Color(0xff777777),
height: 1.4285714285714286,
),
textAlign: TextAlign.left,
onChanged: (String value) async {
},
onSubmitted: (String value) async {
},
),
),
),
],
),
);
}
}
As mentioned before, both inputs show on the screen (one at the center and one at the top) only the TextField wrapped with a SizeBox (first element of the Stack, at the top of the sreen)can be tapped, nothing happens when the one at the center of the screen (second element of the stack, located there because of the translation) is tapped.
Try debugging and see the layout grid lines and correct boundaries of widget using Flutter inspector.
That should give you a better idea at why is it behaving this way.
Seems like when You use the Transform widget, it doesnt register the hit as it merely moves the boundaries and not the tap area.
Try wrapping the Transform widget with a GestureDetector and see.
You can also follow a similar issue on GitHub:
https://github.com/flutter/flutter/issues/27587

How to pass retrieved text to textfield Flutter

I am using speech to text (speech_recognition ) plugin and retrieving text from voice but how can i put the text in to the search field (TextField) after retrieving text. So i want to retrieve data from voice and search it.
here is my code:
// Here is retrieved text inside container
Container(
child: Center(
child: Text(
(transcription.isEmpty)
? "Speak to Record"
: "Your text is \n\n$transcription",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.pink, fontSize: 20),
),
),
),
// Here is my SearchField (TextField)
Padding(
padding: const EdgeInsets.all(20),
child: TextField(
onChanged: (text) {
_con.refreshSearch(text);
},
onSubmitted: (text) {
_con.saveSearch(text);
},
controller: _searchController,
autofocus: true,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(12),
hintText: S.of(context).search_for_product,
hintStyle: Theme.of(context)
.textTheme
.caption
.merge(TextStyle(fontSize: 14)),
prefixIcon:
Icon(Icons.search, color: Theme.of(context).accentColor),
border: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).focusColor.withOpacity(0.1))),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).focusColor.withOpacity(0.3))),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).focusColor.withOpacity(0.1))),
suffixIcon: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: [
InkWell(
onTap: scanBarcode,
child: Image.asset(
"assets/img/barcode.png",
height: 20,
color: Colors.deepOrangeAccent,
),
),
_buildVoiceInput(
onPressed: _speechRecognitionAvailable && !_isListening
? () => start()
: () => stop(),
label: _isListening ? S.of(context).listening : '',
),
],
),
),
),
),
Taking the transcription value into consideration, which is responsible of having the text, what you can do is to make use of it, and change the data using Search TextEditingController.
So, here what I am taking about. I am not sure where are you fetching the data actually, but you can change the values, as soon as you get the data from the voice like this, and assign it to the Controller to fill the Search Field
// Suppose you are fetching the data from this method,
void fetchTextFromVoice(){
setState(() {
// Here you might be assigning the value to the Transcript value
this.transcription = data_from_voice;
// also this does the magic, which will put the data inside the Search Field
// Your TextEditingController is the key to do that
_searchController.text = data_from_voice;
// or _searchController.text = transcription; Since transcript has some value
});
}
Also, read about TextEditingController Class on what all are the operations you can perform using it. More knowledge to you on this Class will help you in great extent :)
I hope that helps, if not, then please show me where is the function where you are setting the value to transcription. You can assign the value to the same place, like above to _searchController.text and you are good to go. Let me know :)

How to always show hint in text field not only when it is clicked in flutter?

I have a custom text field but as shown in the picture, the bottom text fields looks so vague and empty, I'd like to keep the hint showing even if the field is not focused, how do I achieve that in flutter?
here is my widget code:
Container(
margin: EdgeInsets.all(20),
child: TextFormField(
autofocus: true,
textAlign: TextAlign.right,
decoration: InputDecoration(
enabledBorder: const OutlineInputBorder(
borderSide: const BorderSide(color: Color(0xff0E9447), width: 2.0),
),
focusedBorder: const OutlineInputBorder(
borderSide: const BorderSide(color: Color(0xff0E9447), width: 2.0),
),
hintText: AppStrings.email,
labelText: AppStrings.email,
alignLabelWithHint: true,
hintStyle: TextStyle(color: AppColors.primaryColorLight),
),
),
),
If you would like the label to be visible at the top of the TextField, and the hint displayed at the same time you can simply add:
floatingLabelBehavior: FloatingLabelBehavior.always
to the TextFields InputDecoration (decoration).
(At the time of writing this, there is a bug that will only show the hint and suffix upon focus, this has been fixed in a very recent PR and will be available shortly, see GitHub issue)
Full Example
TextFormField(
controller: textController,
style: theme.textTheme.bodyText2,
keyboardType: keyboardType ?? TextInputType.number,
enableInteractiveSelection: false,
decoration: InputDecoration(
labelText: labelText,
labelStyle: theme.textTheme.headline6,
suffixText: suffixText ?? '',
border: OutlineInputBorder(
borderSide:
BorderSide(color: theme.textTheme.bodyText2.color, width: 2),
),
hintText: '0.0',
floatingLabelBehavior: FloatingLabelBehavior.always),
validator: (value) {
if (value.isEmpty) {
return 'Please enter some text';
}
return null;
},
onChanged: (String text) => onChange(text),
);
Ideally in Flutter you cannot do this as both hintText and labelText behave in two different ways. labelText is shown as hintText as long as the user does not focus on it. As soon as the user clicks on the TextField, the labelText animates to a specific position whereas a hintText remains visible until the user types something.
So using labelText and hintText together, does not make any sense as the TextField will wipe of the hintText while animating the label.
However with some extra effort, you can use Stack widget to solve your problem.
Declare a class variable (a variable within the concerned class, outside any block of code) to store a TextEditingController.
TextEditingController _controller;
And initialize in your class' initState(),
_controller= TextEditingController();
Solution Code:
Container(
margin: EdgeInsets.all(20),
child: Stack(
children : <Widget>[
TextFormField(
autofocus: true,
textAlign: TextAlign.right,
decoration: InputDecoration(
enabledBorder: const OutlineInputBorder(
borderSide: const BorderSide(color: Color(0xff0E9447), width: 2.0),
),
focusedBorder: const OutlineInputBorder(
borderSide: const BorderSide(color: Color(0xff0E9447), width: 2.0),
),
labelText: AppStrings.email,
alignLabelWithHint: true,
hintStyle: TextStyle(color: AppColors.primaryColorLight),
),
),
(_controller.text=="")
?
Text(
AppStrings.email,
style: TextStyle(
color: Colors.grey
// Style it according to your requirement / To make it look like hintText
),
)
:
Container();
],
),
),
Basic Logic of the above code: If the TextField does not have any text then display the (hint) Text
widget else don't display anything.
There is a way around this.
Use the labelText property and set floatingLabelBehavior: FloatingLabelBehavior.never.
This way you will always see the hint and when the User clicks on the TextField, it goes away.