Is it possible in Flutter to reuse TextEditingController? - flutter

In my application, there is a lot of TextFields like more than 50.
class BoxFieldItem extends StatelessWidget {
BuildContext context;
final String title;
final String subtitle;
TextEditingController textControler;
BoxFieldItem(this.title,this.subtitle,){
textControler=new TextEditingController();
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
textInputAction: TextInputAction.next,
controller: textControler,
/* onChanged: (String e) {
},*/
decoration: InputDecoration(
fillColor: Colors.lightBlue[40],
filled: true,
prefixIcon: Icon(Icons.person),
labelText: title,
hintText: subtitle,
hintStyle: TextStyle(fontSize: 12),
border:
OutlineInputBorder(borderRadius: BorderRadius.circular(10))),
),
);
}
}
I have this Widget class ,trouble is when i use it like: BoxFieldItem('Title','sub'), text entered disapiar if i scroll or click next?
What im doing wrong

Depending on your implementation. I would create a widget that wrap the TextField and its controller then in your page you just need use the created widget and provide different configurations via constructor.
To listen for changes in the TextField you can just provide a callback to be used in your page.

Related

How to pass flutter textFormField onChange and onSubmitted as a parameter?

I'm trying to create a custom TextFormField that will accepts parameters that I needed like labelText, controller or prefixIcon etc. What I don't know is how to pass a function to an OnChange and onSubmitted events. Please check the sample code below.
utils.dart
class TextFieldTemplate extends StatelessWidget {
final String initialValue;
final String labelText;
final String hintText;
final IconData prefixIcon;
final TextEditingController controller;
final Function onTap;
TextFieldTemplate(
{this.initialValue,
this.labelText,
this.prefixIcon,
this.controller,
});
#override
Widget build(BuildContext context) {
return TextFormField(
onChanged: (){},
onSubmitted: (){},
controller: controller,
decoration: InputDecoration(
contentPadding: decorationPadding,
labelText: labelText,
prefixIcon: prefixIcon != null
? Icon(
prefixIcon,
)
: null,
),
);
}
}
Usage for the TextFieldTemplate:
var _personName = TextEditingController();
#override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
childtren[
TextFieldTemplate(
labelText: 'Person Name',
controller: _personName,
prefixIcon: Icons.person,
// onSubmitted : ???
// OnChange : ???
),
]
),
);
}
You can pass onChanged and onSubmitted parameter like this
Function(String) onChanged;
Function(String) onSubmitted;
And use like this
TextFieldTemplate(
labelText: 'Person Name',
controller: _personName,
prefixIcon: Icons.person,
onSubmitted: (value){},
onChanged: (value){},
),

Flutter TextFormField disable keyboard but allow accept input

I am writing a scanner app where the app will be installed on a Scanner that runs Android.
Inside the app there is a TextFormField waiting the input scan or paste in the text inside to do other API call.
However I do not find any option for TextFormField to disable the soft keyboard but still can accept input text
Below is my scanner TextFormField widget code that I have tried.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class BuildScannerBar extends StatefulWidget {
final Function onFieldSubmitted;
final TextEditingController textFieldController;
final String labelText, hintText;
final bool disableKeyboard;
BuildScannerBar({
#required this.textFieldController,
#required this.onFieldSubmitted,
this.disableKeyboard = true,
this.labelText = 'Barcode Scan',
this.hintText = '',
});
#override
_BuildScannerBarState createState() => _BuildScannerBarState();
}
class _BuildScannerBarState extends State<BuildScannerBar> {
#override
Widget build(BuildContext context) {
return Align(
alignment: Alignment.topCenter,
child: Container(
height: 75,
margin: EdgeInsets.only(top: 50),
width: 300
decoration: BoxDecoration(
color: Colors.white,
),
child: ListTile(
title: TextFormField(
controller: widget.textFieldController,
decoration: InputDecoration(
border: InputBorder.none,
labelText: widget.labelText,
hintText: widget.hintText,
onTap: () {
SystemChannels.textInput.invokeMethod('TextInput.hide');
},
onFieldSubmitted: widget.onFieldSubmitted),
),
),
);
}
}
//Create a custom Textfield Widget extending editable:
//=====CUSTOM WIDGET TO HIDE KEYBOARD WHILE ACCEPTING VALUE FOR BARCODE CODE SCANNER DEVICE =====//
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class TextFieldWithNoKeyboard extends EditableText {
TextFieldWithNoKeyboard(
{#required TextEditingController controller,
#required TextStyle style,
#required Function onValueUpdated,
#required Color cursorColor,
bool autofocus = false,
Color selectionColor})
: super(
controller: controller,
focusNode: TextfieldFocusNode(),
style: style,
cursorColor: cursorColor,
autofocus: autofocus,
selectionColor: selectionColor,
backgroundCursorColor: Colors.black,
onChanged: (value) {
onValueUpdated(value);
});
#override
EditableTextState createState() {
return TextFieldEditableState();
}
}
//This is to hide keyboard when user tap on textfield.
class TextFieldEditableState extends EditableTextState {
#override
void requestKeyboard() {
super.requestKeyboard();
//hide keyboard
SystemChannels.textInput.invokeMethod('TextInput.hide');
}
}
// This hides keyboard from showing on first focus / autofocus
class TextfieldFocusNode extends FocusNode {
#override
bool consumeKeyboardToken() {
return false;
}
}
// Use this custom widget in your screen by replacing TextField //with, TextFieldWithNoKeyboard
//=====Below is example to use in your screen ==//
class QRCodeScanner extends StatefulWidget {
QRCodeScanner({Key key}) : super(key: key);
#override
_QRCodeScannerState createState() => _QRCodeScannerState();
}
class _QRCodeScannerState extends State<QRCodeScanner> {
TextEditingController scanController = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: TextFieldWithNoKeyboard(
controller: scanController,
autofocus: true,
cursorColor: Colors.green,
style: TextStyle(color: Colors.black),
onValueUpdated: (value) {
print(value);
},
),
),
);
}
}
Just set readOnly to true, and keyboardType to TextInputType.none as shown in the code bellow :
TextFormField(
keyboardType: TextInputType.none,
readOnly: true,
....
Juste add
// readOnly: true
TextFormField(
readOnly: true
controller: widget.textFieldController,
decoration: InputDecoration(
border: InputBorder.none,
labelText: widget.labelText,
hintText: widget.hintText,
onTap: () {
SystemChannels.textInput.invokeMethod('TextInput.hide');
},
onFieldSubmitted: widget.onFieldSubmitted),
),

Custom controller for TextFormField clears text entered when focus removed - Flutter

I have created a custom controller for TextFormField, but I use it in my widgets it clears the input upon releasing focus from the input. the same setup works fine with the local widget set up with the same but I want to have a common widget to use throughout the application for better code maintainability. How can have the input intact entered into the input field??
Custom Input Widget-
import 'package:HSSE/screens/constant.dart';
import 'package:flutter/material.dart';
class AppInput extends StatelessWidget {
const AppInput(
{Key key,
this.correct = false,
this.hintText,
this.inputLabel,
this.labelFont = 18.0,
this.labelFontWeight,
this.validators,
this.keyboard,
this.length,
this.icon,
this.trailingIcon,
this.readOnly = false,
this.inputController,
this.onTap = null,
this.onInputValueChange,
this.labelText})
: super(key: key);
final bool correct;
final String hintText;
final String labelText;
final String inputLabel;
final double labelFont;
final FontWeight labelFontWeight;
final Function validators;
final Function onInputValueChange;
final TextInputType keyboard;
final int length;
final Icon icon;
final Icon trailingIcon;
final bool readOnly;
final Function onTap;
final TextEditingController inputController;
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
border: Border.all(color: Color(0Xffcacaca), width: 0.75),
borderRadius: BorderRadius.circular(10),
),
padding: EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
labelText,
style: TextStyle(fontSize: labelFont),
),
TextFormField(
readOnly: readOnly,
keyboardType: keyboard,
maxLength: length,
controller: inputController,
cursorColor: apmt_color,
decoration: InputDecoration(
prefixIcon: icon,
suffixIcon: trailingIcon,
errorStyle: TextStyle(
fontSize: 16,
),
border: InputBorder.none,
hintText: hintText,
labelStyle: TextStyle(
color: Colors.black,
),
fillColor: Colors.red,
),
style: TextStyle(color: Colors.black),
onChanged: (value) {
onInputValueChange(value);
},
validator: (value) {
return validators(value);
},
)
],
),
);
}
}
When I use it into my other widget like below -
final TextEditingController emailCtrl = TextEditingController();
AppInput(
inputController: emailCtrl,
keyboard: TextInputType.emailAddress,
hintText: Localizer.of(context).translate('inspectorNameHint'),
labelText: Localizer.of(context).translate('inspectorName'),
validators: (String name) {
if (name.isEmpty)
return Localizer.of(context)
.translate('inspectorNameError');
},
)
the input gets clears when the focus gets removed from the input field it works fine with the same setup on the local widget but I want to make a common widget to optimize the code.

Flutter - Hide hint text when Text Field have focus

I need to know how to hide the hint text when I focus on the text field. This is my code:
class _ContactoState extends State<Contacto> {
FocusNode focusMsj;
#override
void initState() {
super.initState();
focusMsj = FocusNode();
focusMsj.addListener(() {
if (!focusMsj.hasFocus) {
FocusScope.of(context).requestFocus(focusMsj);
}
});
}
TextField(
focusNode: focusMsj,
hintText: focusMsj.hasFocus ? ' ' : 'Hint Text',)
return WillPopScope(
child: Listener(
onPointerUp: (e) {
focusMsj.hasFocus ? FocusScope.of(context).requestFocus(FocusNode()): '';
},
Thank you
For doing that matter you need to make something like that
class Play extends StatefulWidget {
#override
_PlayState createState() => _PlayState();
}
class _PlayState extends State<Play> {
FocusNode focusNode = FocusNode();
String hintText = 'Hello , iam Hint';
#override
void initState() {
// TODO: implement initState
super.initState();
focusNode.addListener(() {
if (focusNode.hasFocus) {
hintText = '';
} else {
hintText = 'Hello , iam Hint';
}
setState(() {});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(onPressed: () {
print(focusNode.hasFocus);
}),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
focusNode: focusNode,
decoration: InputDecoration(
hintText: hintText,
),
),
TextField(
decoration: InputDecoration(
hintText: '!!',
),
),
],
),
),
);
}
}
Shortly i listened to TextField by its focusNode property . When TextField has focus i make hintText property equal empty String value
There is a property for that:
TextField(decoration: InputDecoration(hasFloatingPlaceholder: false));
Edit: The version above is deprecated, the new version is:
TextField(decoration: InputDecoration(floatingLabelBehavior: FloatingLabelBehavior.never,),),
One simple solution you can try is define labelText with FloatingBehavior.never
TextField(
decoration: InputDecoration(
labelText: "Search",
floatingLabelBehavior: FloatingLabelBehavior.never,
)
)
HintText will be shown when it is not focussed. On focus, hint text will disappear.
Simply, don't add the hintText in the InputDecoration and mention only the labelText: 'Label' alongside labelStyle if you want to change the style of the label.
TextField(
decoration: InputDecoration(
labelText: "Label",
labelStyle: TextStyle(
color: Colors.blueGrey,
),
floatingLabelBehavior: FloatingLabelBehavior.never,
)
)
My understanding is there is no way to implement it without custom code. Hiding hintText when focused with "border: InputBorder.none," gives perfect login widget example as FloatingLabelBehavior and having animated labelText just won't do. floatingLabelBehavior: FloatingLabelBehavior.never - helps in some situtations but not the exact thing we wanted. If you have labelText and hintText FloatingLabelBehavior.never is helpful to control hiding and showing hintText and animating labelText above the field. WIth custom code we have
String emailHintText = "E-mail";
on the top of state class. Then:
Container(
decoration: BoxDecoration(
border: Border.all(color: white),
borderRadius: BorderRadius.circular(5)),
child: Padding(
padding: EdgeInsets.all(10),
child:
Focus(
onFocusChange: (hasFocus) {
if (hasFocus) {
setState(() {});
emailHintText = "";
}
else {
setState(() {});
emailHintText = "E-mail";
}
},
child: TextFormField(
decoration: InputDecoration(
hintText: emailHintText,
border: InputBorder.none))));
Now, you should know that using setState is a bit costly operation and may not be the best option if not used for very important functionalities.
This works perfectly for me. Just add on InputDecoration ( floatingLabelBehavior: FloatingLabelBehavior.never) of TextField or TextFormField.
TextFormField( controller:_controller, decoration : InputDecoration( label: Text('Entrer your code here '), floatingLabelBehavior: FloatingLabelBehavior.never, ), );

I make a class of Textfield.But when I try to call value,it can't get the real value of the text in the textfield via controller

This is my code.When I try to get RxInput.value,I get nothing.How to deal with it?Where is the problem?
I want to make it easy for me to use the decorated textfield.So I build this class.How to solve it????
I am about to be crazy.
import 'package:flutter/material.dart';
class RxInput {
_RxInput rx;
final String hindText;
final bool obscureText;
Widget get widget => rx;
final TextEditingController controller = new TextEditingController ();
String get value => controller.text;
RxInput (this.hindText,context,{this.obscureText = false}) {
rx = _RxInput (hindText,obscureText,controller);
}
}
class _RxInput extends StatefulWidget{
final TextEditingController controller;
_RxInput (this.hindText,this.obscureText,this.controller);
final String hindText;
final bool obscureText;
#override
createState () {
return _RxInputState ();
}
}
class _RxInputState extends State <_RxInput>{
Padding data;
#override
void initState() {
data = Padding (
padding: const EdgeInsets.all(20.0),
child: Material(
borderRadius: BorderRadius.circular(20.0),
shadowColor: Colors.blue.shade200,
elevation: 5.0,
child:TextField(
controller: widget.controller,
decoration: InputDecoration(
hintText: widget.hindText,
border: InputBorder.none,
alignLabelWithHint: true,
),
obscureText: widget.obscureText,
)
),
);
super.initState();
}
#override
Widget build(BuildContext context) {
return data;
}
}
Do like this
1. Create a Class with Meaningful Name for eg.Helper Class
2. And Implement below Textfield Method
Widget textField(String hint, TextEditingController controller,
{TextInputType keyboardType = TextInputType.text,
bool obscure = false,
VoidCallback onEditingComplete}) {
return SizedBox(
height: 45,
child: TextField(
onEditingComplete: onEditingComplete,
obscureText: obscure,
controller: controller,
keyboardType: keyboardType,
decoration: InputDecoration(
contentPadding: textFieldPadding(),
hintText: hint,
border: OutlineInputBorder(),
),
inputFormatters: [LengthLimitingTextInputFormatter(maxLength)],
),
);
}
And just simply use it by importing a particular class library put it wherever you want and let me know it is working for you or not?