Reputation: 1088
I want to have a multiline textfield where some paragraph data can be returned. I changed the 'new line' button to 'done' button using the textInputAction property, and though it calls onEditingComplete, it is still not exiting the textfield. I know it has something to do with focus but i am not able to figure out exactly how to do it.
This is my code
TextField(
onChanged: (text){
print('On changed is called');
},
onEditingComplete: (){
print('Editing is done ');
},
textInputAction: TextInputAction.done,
maxLines: 6 ,
controller: textEditingController,
decoration: InputDecoration(
.....
)
),
How can i de-focus on pressing done? Thanks in advance
Upvotes: 10
Views: 9386
Reputation: 19434
It is now possible to set keyboardType
to text
and textInputAction
to done
for maxLines>1
maxLines: 3,
textInputAction: TextInputAction.done,
keyboardType: TextInputType.text,
Upvotes: 2
Reputation: 21955
The accepted answer has a problem. It mandates that you use TextInputAction.done
which seriously limits the functionality of multiline TextFormField
. A simple solution is to use a focusNode along with a toggle
. The toggle is activated when the form field gets focus.
Assuming that the top level elements are children of the same column, something like below would suffice
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
focusNode.hasFocus
? FlatButton(
color: Colors.green,
child: Row(
children: <Widget>[
FaIcon(
Icons.done,
color: Colors.white,
),
SizedBox(
width: 5.0,
),
Text(
'Done',
style: Theme.of(context).textTheme.body1.copyWith(
fontWeight: FontWeight.w700,
color: Colors.white,
),
),
],
),
onPressed: () {
setState(() {
FocusScope.of(context).unfocus();
});
},
)
: Text(''),
],
),
Card(
child: TextFormField(
focusNode: focusNode, // The focusNode should be properly initiated and disposed
controller: jobSpecificsController,
maxLines: 3,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.done,
decoration: formElementDecoration.copyWith(hintText: 'Please enter the job details.'),
onTap: () {
setState(() {}); // Without this setState, you won't get the toggle in the iOS.
},
),
),
Upvotes: 0
Reputation: 969
You can use FocusNode to control the focus.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MyApp',
home: MyWidget(),
);
}
}
class MyWidget extends StatefulWidget {
@override
State<MyWidget> createState() {
return _MyWidget();
}
}
class _MyWidget extends State<MyWidget> {
FocusNode _focusNode;
@override
void initState() {
super.initState();
_focusNode = FocusNode();
}
@override
void dispose() {
super.dispose();
_focusNode.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: TextField(
focusNode: _focusNode,
maxLines: 8,
autofocus:false ,
textInputAction: TextInputAction.done,
onEditingComplete: () {
print("edit");
_focusNode.unfocus();
},
),
)
);
}
}
Upvotes: 9
Reputation: 513
Have you tried it at the onSubmitted:
method?
TextField(
focusNode: myFocus,
onSubmitted: (text) {
myFocus.unfocus();
},
),
Upvotes: 0
Reputation: 5793
Just make maxLine: null as shown below
new TextFormField(
controller: controller,
obscureText: obscure,
focusNode: _focusNode,
maxLines: null,
keyboardType: inputtype,
onSaved: (String val) {
text = val;
},
decoration: new InputDecoration(labelText: hintText,
enabledBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.transparent)),
focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.transparent)),
labelStyle: TextStyle(color: const Color(0xFF0C0738))),
)
Upvotes: 0