I have a form page and there are several TextFields and I want to call a function after clicking outside of one specific textfield. Is there any parameter of TextField that can serve my purpose or any way to do that?
TextFormField have focusNode property, focusNode have addListener callback. which get called when TextFormField having focus and when textformfield losing its focus, with the help of focusnode we can call method when clicking outside specific textfield.
class _MyWidgetState extends State<MyWidget> {
FocusNode firstFocusNode = FocusNode();
FocusNode secondFocusNode = FocusNode();
#override
void initState() {
super.initState();
firstFocusNode.addListener(() {
if (!firstFocusNode.hasFocus) {
method();
}
});
}
void method() {
print("User clicked outside the Text Form Field");
}
#override
void dispose()
{
firstFocusNode.removeListener((){});
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(children: [
TextFormField(focusNode: firstFocusNode),
TextFormField(
focusNode: secondFocusNode,
)
]));
}
}
the solution you are looking for is gestureDetector, but it depends where you want to call the function if you want to call the function only when tapped inside the form area but outside the textfield then wrap the form with gesture detector and use onTap: (){}, or if you want to call the same on whole screen tapped but outside the textfield wrap it around the whole scaffold.
new Scaffold(
body: new GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(new FocusNode());
//this function will remove the keyboard.
},
Related
There's a button on my home page which when clicked should redirect me to another page and click on textformfield on that page,I dont know how to do that
just use autofocus: true on another page
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: TextButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) {
return NextPage();
},
));
},
child: Text("Click")),
),
);
}
}
class NextPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: TextField(
autofocus: true,
),
);
}
}
There is multiple ways to do this depending on your use case
1- if you want to focus on the text form field every time you enter the page you change autofocus property in the textField to true,
TextField(
autofocus:true,
)
2- if you want to trigger focus on a textfield by manually you can use FocusNode object, this focus node will be attached to your text field.
First you need to initialize the object.
FocusNode myFocusNode;
#override
void initState() {
super.initState();
myFocusNode = FocusNode();
}
#override
void dispose() {
// Clean up the focus node when the Form is disposed.
myFocusNode.dispose();
super.dispose();
}
then Attach the focus node object to your text field
TextField(
focusNode: myFocusNode,
);
Now you can use this focus node in a function to focus on this text
// focus on textfield (same as text field pressed)
myFocusNode.requestFocus()
// unfocus on textfield (same as pressing done on textfield or pressing the back button)
myFocusNode.unfocus()
you can pass a flag to the new page you are going to, which will trigger the focus function
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.
I have an appBar with a search button, which when pressed returns a custom DataSearch class that extends SearchDelegate.
When I close the search page (from the device's go back button or from the widget), I need to execute a certain function first.
However the function is only executed from the below widget and not when the device's "BACK" button is pressed.
(Image below)
Here's my code:
class DataSearch extends SearchDelegate<String> {
#override
List<Widget> buildActions(BuildContext context) {
// ...
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
function_I_need_to_execute();
close(context, null);
},
);
}
#override
Widget buildResults(BuildContext context) {
// ...
}
#override
Widget buildSuggestions(BuildContext context) {
// ...
}
}
I've tried this, but no changes:
#override
void close(BuildContext context, String result) {
super.close(context, result);
function_I_need_to_execute();
}
I'm considering using the WillPopScope widget but I'm not sure where it fits in the delegate.
Image:
Seems this is not possible using the close method.
However you can do this using the .then method on showSearch since showSearch is a Future.
The then method registers callbacks to be called when this future completes.
showSearch(context: context, delegate: SearchDelegate()).then((value) async{
await doSomething();
});
I am very new to Flutter and Dart so I am trying to build a simple search app with queries based on a word typed in Flutters showSearch search bar. I understand the listtile that is built to show suggestions to the user, and tapping that suggestion will activate the buildresults widget. However, I want to enable the search button on the keyboard to simply search the inputted word, rather than tapping on the limited suggestion list.
Simple android keyboard
When the button is clicked normally, the keyboard is closed the buildresults is not activated. So far you have to actually click a suggested listtile option. Is there a way to enable the keyboard's search button to search the inputted text? or Is the user limited to the suggested listtile options? I will list my showSearch delegate below:
class StockDelegate extends SearchDelegate<String> {
final stocks = [
"IBM",
"NKLAW",
"DKNGZ",
"DRD",
"PRTS",
"TSLA",
"KIRK",
"VBIV"
];
final suggested = ["IBM", "TSLA", "BNTX"];
#override
// TODO: implement textInputAction
// TODO: implement textInputAction
TextInputAction get textInputAction => super.textInputAction;
#override
List<Widget> buildActions(BuildContext context) {
//actions for app bar
StockProvider _stockProvider =
Provider.of<StockProvider>(context, listen: true);
return [
IconButton(
icon: Icon(Icons.clear),
onPressed: () {
query = '';
}),
];
}
#override
Widget buildLeading(BuildContext context) {
//Leading icon on the left of the app bar
return IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow,
progress: transitionAnimation,
),
onPressed: () {
close(context, null);
});
}
#override
Widget buildResults(BuildContext context) {
//build results code
}
#override
Widget buildSuggestions(BuildContext context) {
// show when someone search for something
stocks.insert(0, query.toString());
final suggestionList = query.isEmpty
? suggested
: stocks.where((p) => p.startsWith(query)).toList();
return ListView.builder(
itemCount: suggestionList.length,
itemBuilder: (context, index) => ListTile(
onTap: () async {
Provider.of<StockProvider>(context, listen: false)
.searchBySymbol(suggestionList[index]);
if (!stocks.contains(suggestionList[index]))
suggestionList.add(suggestionList[index]);
showResults(context);
},
leading: Icon(Icons.attach_money),
title: Text(suggestionList[index]),
),
);
}
I don't know whether you know about onSubmitted property or not, which is used in the TextField/Text/TextFormField. Since, I cannot see your TexFormField/Text/TextField anywhere, but I think you must be using it somewhere.
So, this is how onFieldSubmitted used, which does the job which you want, that is, when the user hit on the magnifying lens on the keypad, it runs your function
TextFormField(
controller: _yourTextEditingController,
textInputAction: TextInputAction.search,
onFieldSubmitted: (){
// here you do your operation when you hit the
// keypad magnifying lens
// check with print()
print('Pressed via keypad');
}
)
Don't get confused with onSubmitted name, onFieldSubmitted is used in TextFormField/Text/TextField, which uses onSubmitted property. I hope that answers your question :) Let me know, is that was the thing you were looking for.
Override showResults() method similar to buildSuggestions().
override showResults method as follow:
#override
void showResults(BuildContext context) {
super.showResults(context);
showSuggestions(context);
FocusScope.of(context).unfocus();
}
If I have this:
class SomethingState extends State<Something> {
String name;
#override
Widget build(BuildContext context) {
return TextField(
onChange: (text) {
name = text
}
)
}
}
Do I have to wrap name = text in setState to trigger the build method or no because when the user types something in the TextField it already does that?
This is how I have it now and it works, but I want to make sure I understand this correctly.
The value will change without setState but will not change on the UI. To update the UI you must use setState and rebuild the widgets.
This code for the question in the comments
class Homepage extends StatelessWidget {
final controller = TextEditingController();
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Center(child: TextField(controller: controller,),),
FlatButton(child: Text("change"),onPressed: (){
controller.text = 'new text';
},)
],
);
}
}