Is there a way in Flutter to force that the keyboard which opens once I click the TextForm is in English?
I want a TextField to contain only English characters. Is there a way?
Use the following to open default keyboard app with predefined language.
FocusScope.of(context).requestFocus(FocusNode());
There is no way to launch the keyboard in particular language. Users have to do that from their end in keyboard settings. However you may use the RegExp to check if all the characters are in English.
May be this helps!
SystemChannels.textInput.invokeMethod('TextInput.show');
whenever requestFocus is invoked to prevent this situation:
As far as I know, there isn't a way to launch the keyboard in a language.
To open keyboard with the predefined language you need to enable autoFocus in the TextField widget like this:
TextField(
autofocus: true,
)
class _MyHomePageState extends State<MyHomePage> {
final _focusNode = FocusNode();
#override
void initState() {
super.initState();
}
#override
void dispose() {
_focusNode.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
RaisedButton(
child: Text('PROVIDE FOCUS'),
onPressed: () {
FocusScope.of(context).requestFocus(_focusNode);
SystemChannels.textInput.invokeMethod('TextInput.show');
},
),
IgnorePointer(
child: TextField(
focusNode: _focusNode,
),
)
],
),
);
}
}
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 am trying to show text selection without keyboard.
It seems that triggering 'TextInput.show' always bring up keyboard.
But somehow without 'TextInput.show' I cannot select target text.
I wonder if there is alternative to select text without keyboard.
You can use TextFormFiled from flutter material package.
so first import material package to your class
import 'package:flutter/material.dart';
then create TextFormFiled in Your Widget any where you want
TextFormField(),
then create controller in top of the build method.you can control text using controller later
TextEditingController _controller = TextEditingController();
then you can hide keybord popup automatically by
TextFormField(
autofocus: false,
),
but it shows when you tap the TextFormFiled. so do you want to hide keyboard also tap state set as follows
TextFormField(
onTap: (){
FocusScope.of(context).unfocus();
},
),
Full code :
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class TestScreen extends StatelessWidget {
TextEditingController _controller = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: TextFormField(
controller: _controller,
onTap: (){
FocusScope.of(context).unfocus();
},
),
),
);
}
}
Happy Coding;
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();
}
Pretty much what I describe in the title. I have a pile of TextFormFields populated from Firebase when the app launches.
The user should be able to update these, and when they are done, click a submit button to update the database. The database code all works, however there is some bug which works as follows:
TextFormField1: "New Text Entered"
TextFormField2: "Some more text"
TextFormField3: "Another update here"
Now we get to a point where we need to dismiss the keyboard, so that we can see the submit button underneath. As soon as you click the little down arrow to dismiss the keyboard, all the changes above revert back to their original state.
Anyone seen this?
I am prepopulating the data in these fields at runtime, and you can edit and update the text, and it all works fine... except if you minimise the keyboard.
Please tell me that Flutter isn't doing something fundamentally stupid like reloading the widget underneath from scratch every time you ask the keyboard to go away...... It sort of feels like it is.
Yes. It happens to me all the time. It is because the screen rebuilds when the bottom insets (due to keyboard) changes.
Enclose the TextFormField(s) inside a Form and give it a global key.
Use a local variable to store the value of the TextFormField. Update it in onChanged method.
All done!
I shall attach a code for easiness.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: LoginScreen(),
);
}
}
// Login Screen
class LoginScreen extends StatefulWidget {
#override
_LoginScreenState createState() => _LoginScreenState();
static GlobalKey<FormState> _loginScreenFormKey = GlobalKey<FormState>();
}
class _LoginScreenState extends State<LoginScreen> {
String username;
String password;
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Form(
key: LoginScreen._loginScreenFormKey,
child: Column(
children: [
TextFormField(
decoration: InputDecoration(
hintText: 'Enter username',
),
onChanged: (value) {
setState(() {
username = value;
});
},
),
TextFormField(
decoration: InputDecoration(
hintText: 'Enter username',
),
onChanged: (value) {
setState(() {
password = value;
});
},
obscureText: true,
),
RaisedButton(
onPressed: () {
LoginScreen._loginScreenFormKey.currentState.save();
},
child: Text('submit'),
),
],
),
),
),
);
}
}
This is my solution: move the TextEditingController variable from the inside of the "build" method to the outside of the "build" method. Ref in pic The solution
The class that includes those TextFormFields should extends State of StatefulWidget, the local state will be cleared if the dismiss of keyboard causes those fields re-render, hence you need StatefulWidget to save the local state so that it won't be re-rendered
Convert you StatelessWidget to StatefulWidget.
usually I can disable/grey-out a button until a TextFormField meets certain parameters in flutter by something like this:
TextFormField(
controller: _controller
value: (value)
)
SubmitButton(
onPressed: _controller.text.isNotEmpty ? _submit : null;
)
But when compiled as a website the Button seems no longer aware of the controller value...
I have tried targeting in several different ways, e.g. _controller.value.text.isEmpty and _controller.text.isEmpty...
I'm guessing I'm missing something or this method just isn't possible for web ... Is there any other way to get the same result?
To be honest, your code shouldn't work in flutter mobile either, but may be works because of screen keyboard causes widget rebuild when showing or hiding.
To fix this issue we have to use stateful widget with state variable like canSubmit and update it in textField's listener onChange with setState method. Then every time the text changes, our stateful widget will update the submit button..
class Page extends StatefulWidget {
#override
_PageState createState() => _PageState();
}
class _PageState extends State<Page> {
bool canSubmit;
#override
void initState() {
canSubmit = false;
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
TextField(
onChanged: (value) {
setState(() {
canSubmit = value.isNotEmpty;
});
},
),
RaisedButton(
onPressed: canSubmit ? _submit : null,
child: Text('Submit'),
)
],
),
),
);
}
void _submit() {
print('Submitted');
}
}