flutter, next page with a variable controller - android

Excuse me guys, i tryin to build a new page, but with variable "nextcode" in it. so in the new page, it will show nextcode text
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Lemari(nextcode)));
},
but in the line "Widget build(String Kode) {" it must be like this "Widget build(BuildContext context) {"
class Lemari extends StatelessWidget {
#override
Widget build(String Kode) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue[900],
title: Text('this is th next page'),
),
backgroundColor: Colors.white,
body: Center(
child: Column(
children: [
Container(height: 100, width: 100, color: Colors.red, child: Text('hhe'),),
]
),
),
);
}
}
So anyone who can help me ? please :(

You don't have to change the build method parameters instead you should add a new parameter in the widget and require it
Example
const MyPageView({Key? key}) : super(key: key);
Here you can add another parameter.
Then inside the class you define that parameter.. so when you make a new MyPageView you will have to pass the newly added parameter
Bye :)

Your code should have a compiler error
In Lemari , you never declare nextcode and constructor also do not have parameter nextcode.
You can try like this, add
class Lemari extends StatelessWidget {
final String nextcode;
const Lemari({Key key, this.nextcode}) : super(key: key);
#override
Widget build(BuildContext context) {}
}
if your nextcode is String

Related

type 'Null' is not a subtype of type 'Function'

I am new to Flutter. I am building a quiz app and have the following three dart files:
main.dart
import 'package:flutter/material.dart';
import './answer.dart';
import './question.dart';
void main(){
runApp(MyApp());
}
class MyApp extends StatefulWidget {
State<StatefulWidget> createState(){
return _MyAppState();
}
}
class _MyAppState extends State<MyApp>{
var _questionIndex = 0;
_answerQuestion(){
setState(() {
_questionIndex = _questionIndex + 1;
});
}
#override
Widget build(BuildContext context) {
var questions = [
{'questionText': 'What\'s your favourite color ?',
'answers': ['Red','Blue','White','Black']
},
{'questionText': 'What\'s your favourite Animal ?',
'answers': ['Dog','Rabbit','Tiger','Monkey']
},
{'questionText': 'What\'s your favourite Day ?',
'answers': ['Tuesday','Monday','Sunday','Friday','Wednesday','Saturday']
},
];
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('My First App'),
),
body: Column(
children: [
Question(questions[_questionIndex]['questionText'] as String,
),
...(questions[_questionIndex]['answers'] as List).map((answer) {
return Answer(_answerQuestion(),answer);
}).toList()
],
)
),
);
}
}
question.dart
import 'package:flutter/material.dart';
class Question extends StatelessWidget {
final String questions;
Question(this.questions);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: EdgeInsets.all(10),
child:(
Text(
questions,
style: TextStyle(
fontSize: 25),
textAlign: TextAlign.center,)
),
);
}
}
answer.dart
import 'package:flutter/material.dart';
class Answer extends StatelessWidget {
final Function buttonHandler;
final String answer;
Answer(this.buttonHandler,this.answer);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
child: ElevatedButton(
child: Text(answer),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.blue),
foregroundColor: MaterialStateProperty.all(Colors.white)
),
onPressed: () => buttonHandler,
),
);
}
}
when I run the application on my android in Android studio, I get this error:
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY╞═══════════════════════════════════════════
The following _TypeError was thrown building MyApp(dirty, state: _MyAppState#7f7de):
type 'Null' is not a subtype of type 'Function'
The relevant error-causing widget was:
MyApp file:///C:/src/first_app/lib/main.dart:7:10
This:
onPressed: () => buttonHandler,
needs to be either:
onPressed: buttonHandler,
or
onPressed: () => buttonHandler(),
depending on whether your handler matches the required signature exactly.
In addition, this:
return Answer(_answerQuestion(),answer);
needs to be
return Answer(_answerQuestion,answer);
Generally speaking, you have mixed up calling a method and passing a method as a parameter a few times, you may want to get more familiar with it.
First, you must pass a function structure instead returning value from the function by calling it.
You declared this function below:
_answerQuestion(){
setState(() {
_questionIndex = _questionIndex + 1;
});
}
and passed the return value instead of function structure like below:
return Answer(_answerQuestion(),answer);
As you can see the return value of _answerQuestion() is Null.
Change your code like this.
return Answer(_answerQuestion,answer);
And you need to call the funcion in the Answer component.
onPressed: buttonHandler
or
onPressed: () => buttonHandler()
Your code is working fine try flutter clean

Passing data from a StatelessWidget to a StatefulWidget

I am very new to flutter and I am trying to create a Generic Button widget that I can just pass parameters into (Text, color, etc.) keeping it short to just text right now. So I have setup my main app named SplashScreen and in the body I add the GenericButton class. I would like to know if there is a way for me to pass a string of text or any other kind of data, save that in my GenericButton class so that I can push that into my _GenericButtonState using widget.buttonText
final String _title = "Flutter Demo";
// * This is the landing page
class SplashScreen extends StatelessWidget {
// * This widget is the root of your application.
const SplashScreen({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
theme: ThemeData(
primarySwatch: Colors.deepPurple,
),
home: Scaffold
(
appBar: AppBar
(
title: Text(_title)
),
body: GenericButton() // <-- Statelful Widget I would like to pass data into.
)
);
}
}
// * Creating reusable button
class GenericButton extends StatefulWidget
{
final String buttonText;
const GenericButton(this.buttonText);
#override
_GenericButtonState createState() => _GenericButtonState();
}
class _GenericButtonState extends State<GenericButton>
{
#override
Widget build(BuildContext context)
{
return OutlinedButton(
child: Text(widget.buttonText),
onPressed: ()
{
Navigator.push(
context,
MaterialPageRoute(builder: (context) => LocationsPage()),
);
},
);
}
}
you can do that normally through constructor , this is working example from one of my projects
class PrimaryButton extends StatelessWidget {
final String text;
final Color color;
final Color textColor;
final Function onTap;
final EdgeInsets edgeInsets;
final bool pending;
const PrimaryButton({
Key key,
#required this.text,
#required this.onTap,
this.color = AppTheme.primaryColor,
this.textColor = AppTheme.secondaryColor,
this.edgeInsets = const EdgeInsets.symmetric(vertical: 4.0, horizontal: 16.0),
this.pending = false,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: pending ? null: onTap,
child: Container(
child: Center(
child: pending
? Padding(
padding: const EdgeInsets.all(5.0),
child: SpinKitThreeBounce(
color: AppTheme.scaffoldBackgroundColor,
size: 15.0,
),
)
: Text(
text,
style: AppTheme.textTheme.headline5.copyWith(fontSize: 18.0, fontWeight: FontWeight.bold,color: textColor),
),
),
margin: edgeInsets,
padding: EdgeInsets.all(12.0),
width: double.infinity,
decoration: BoxDecoration(color: color, borderRadius: BorderRadius.circular(8.0)),
),
);
}
}
You have already defined the buttonText parameter. You have to pass a text into it (like the _title), and anytime you want a new text pass that as the new parameter.
Your GenericButton is a StatefulWidget, if the buttonText parameter changes, the widget won't redraw itself. The didChangeDependencies method will be fired and you need to handle the changes manually: update any state inside the _GenericButtonState
But:
If you change the GenericButton to StatelessWidget, any time the buttonText parameter changes the widget will redraw itself.
Conclusion:
As I understood what you want to build, you'd better have a GenericButton StatelessWidget with the parameters and pass them from the parent, which could be the StatefulWidget as that will manage the state of the texts and other arguments.
You can read more about state management here: https://flutter.dev/docs/development/data-and-backend/state-mgmt/options

Why doesn't anything show up the body of this flutter scaffold?

The class in question is invoked from another page with the line
onPressed: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) =>
ProPage(iD: bestRatedPros[index]["ID"])));
},
Where bestRatedPros is a list of maps with the variable iD for the following class -
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class ProPage extends StatefulWidget {
ProPage({Key key, this.iD}) : super(key: key);
final iD;
#override
_ProPageState createState() => _ProPageState(iD);
}
class _ProPageState extends State<ProPage> {
int iD;
_ProPageState(this.iD);
#override
void initState() {
super.initState();
}
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.amber,
extendBodyBehindAppBar: true,
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.white, //change your color here
),
elevation: 0,
backgroundColor: Colors.amber
),
body:
Text("EWFWEFEWEWFWEF",style: TextStyle(color: Colors.black))
);
}
}
The getDataFromBackend function and
all the variables associated with it was meant to be within the body. But Nothing shows up in the body no matter what it is. Even a simple Text widget doesn't. I'm only trying to pass the variable iD from one page to the other without complicating things. The Run log doesn't show any Errors or warnings.
Arun,
See below where your Text is:
Reason for that is that you specified:
extendBodyBehindAppBar: true,
on your Scaffold, so body is expanded and top part of it is hidden behind AppBar

How to call Layouts in flutter?

I'm new in Flutter.
I have a question
How to call layouts in flutter ?
I've been create some layouts that contains a lot of widget.
It's not right if I make every code inside 1 file.
so I decide to put the code for the widgets in every 1 layouts file.
and I dont know how to call them in the home-page.dart that I create.
I mean, if I push THIS (i.e page1.dart), then the page1.dart is appear.
thought that file (page1.dart) is in other directory (not inside lib dir).
I dont know. am I should use ROUTES ?
but I dont know how.
would you like to teach me ?
..............
here are. I have TabBar like this in my home_page.dart:
import 'package:flutter/material.dart';
import 'package:coba/second.dart';
class HomePage extends StatelessWidget {
static String tag = 'home-page';
#override
Widget build(BuildContext ctxt) {
return new MaterialApp(
title: "MySampleApplication",
home: new DefaultTabController(
length: 3,
child: new Scaffold(
appBar: new AppBar(
title: new Text("Hello Flutter App"),
bottom: new TabBar(
tabs: <Widget>[
new Tab(text: "First Tab"),
new Tab(text: "Second Tab"),
new Tab(text: "Third Tab"),
],
),
),
body: new TabBarView(
children: <Widget>[
new Text("You've Selected First"),
new SecondWidget(),
new ThirdWidget(),
]
)
),
)
);
}
}
class SecondWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
second(data: 'Hello there from the first page!'),
),
}
}
class ThirdWidget extends StatelessWidget {
#override
Widget build(BuildContext ctxt) {
return new Column(
children: <Widget>[
Text('halooo'),
Container(
color: Colors.black,
width: 200,
height: 200,
)
],
);
}
}
thank you so much
You can use any name that you want (generally, we have seen xxxScreen.dart or xxxPage.dart, but it is totally up to you).
Import your "destiny" page using in "origin" page using import:
import 'package:myproject/myPageScreen.dart';
Flutter offers 3 options:
Using Navigator:
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
SecondPage(data: 'Hello there from the first page!'),
),
Using Named routes:
Declare you routes in MaterialApp:
MaterialApp(
// Start the app with the "/" named route. In our case, the app will start
// on the FirstScreen Widget
initialRoute: '/',
routes: {
// When we navigate to the "/" route, build the FirstScreen Widget
'/': (context) => FirstScreen(),
// When we navigate to the "/second" route, build the SecondScreen Widget
'/second': (context) => SecondScreen(),
},
);
And then use named route with Navigator:
onPressed: () {
Navigator.pushNamed(context, '/second');
}
Using onGenerateRoute:
Declare this property on your MaterialApp:
return MaterialApp(
// Initially display FirstPage
initialRoute: '/',
onGenerateRoute: _getRoute,
);
And create your route generator :
final args = settings.arguments;
switch (settings.name) {
case '/':
return MaterialPageRoute(builder: (_) =>
FirstPage());
case '/second':
// Validation of correct data type
if (args is String) {
return MaterialPageRoute(
builder: (_) => SecondPage(
data: args,
),
);
}
You can create your router as another file to help to organize your project.

Hide On-Screen Keyboard when tapping outside of the Text Field (Anywhere on the screen) in Flutter [duplicate]

I am collecting user input with a TextFormField and when the user presses a FloatingActionButton indicating they are done, I want to dismiss the on screen keyboard.
How do I make the keyboard go away automatically?
import 'package:flutter/material.dart';
class MyHomePage extends StatefulWidget {
MyHomePageState createState() => new MyHomePageState();
}
class MyHomePageState extends State<MyHomePage> {
TextEditingController _controller = new TextEditingController();
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(),
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.send),
onPressed: () {
setState(() {
// send message
// dismiss on screen keyboard here
_controller.clear();
});
},
),
body: new Container(
alignment: FractionalOffset.center,
padding: new EdgeInsets.all(20.0),
child: new TextFormField(
controller: _controller,
decoration: new InputDecoration(labelText: 'Example Text'),
),
),
);
}
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new MyHomePage(),
);
}
}
void main() {
runApp(new MyApp());
}
For Flutter version 2 or latest :
Since Flutter 2 with null safety this is the best way:
FocusManager.instance.primaryFocus?.unfocus();
Note: using old ways leads to some problems like keep rebuild states;
For Flutter version < 2 :
As of Flutter v1.7.8+hotfix.2, the way to go is:
FocusScope.of(context).unfocus();
Comment on PR about that:
Now that #31909 (be75fb3) has landed, you should use
FocusScope.of(context).unfocus() instead of
FocusScope.of(context).requestFocus(FocusNode()), since FocusNodes are
ChangeNotifiers, and should be disposed properly.
-> DO NOT use ̶r̶e̶q̶u̶e̶s̶t̶F̶o̶c̶u̶s̶(̶F̶o̶c̶u̶s̶N̶o̶d̶e̶(̶)̶ anymore.
F̶o̶c̶u̶s̶S̶c̶o̶p̶e̶.̶o̶f̶(̶c̶o̶n̶t̶e̶x̶t̶)̶.̶r̶e̶q̶u̶e̶s̶t̶F̶o̶c̶u̶s̶(̶F̶o̶c̶u̶s̶N̶o̶d̶e̶(̶)̶)̶;̶
Read more about the FocusScope class in the flutter docs.
Note: This answer is outdated. See the answer for newer versions of Flutter.
You can dismiss the keyboard by taking away the focus of the TextFormField and giving it to an unused FocusNode:
FocusScope.of(context).requestFocus(FocusNode());
Solution with FocusScope doesn't work for me.
I found another:
import 'package:flutter/services.dart';
SystemChannels.textInput.invokeMethod('TextInput.hide');
It solved my problem.
For Flutter 1.17.3 (stable channel as of June 2020), use
FocusManager.instance.primaryFocus.unfocus();
Following code helped me to hide keyboard
void initState() {
SystemChannels.textInput.invokeMethod('TextInput.hide');
super.initState();
}
To dismiss the keyboard (1.7.8+hotfix.2 and above) just call the method below:
FocusScope.of(context).unfocus();
Once the FocusScope.of(context).unfocus() method already check if there is focus before dismiss the keyboard it's not needed to check it. But in case you need it just call another context method: FocusScope.of(context).hasPrimaryFocus
Looks like different approaches for different version. I am using Flutter v1.17.1 and the below works for me.
onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) {
currentFocus.focusedChild.unfocus();
}
}
GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child:Container(
alignment: FractionalOffset.center,
padding: new EdgeInsets.all(20.0),
child: new TextFormField(
controller: _controller,
decoration: new InputDecoration(labelText: 'Example Text'),
),
), })
try this on tap gesture
None of the above solutions don't work for me.
Flutter suggests this -
Put your widget inside new GestureDetector() on which tap will hide keyboard and onTap use FocusScope.of(context).requestFocus(new FocusNode())
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
var widget = new MaterialApp(
home: new Scaffold(
body: new Container(
height:500.0,
child: new GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(new FocusNode());
},
child: new Container(
color: Colors.white,
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
new TextField( ),
new Text("Test"),
],
)
)
)
)
),
);
return widget;
}}
For me, the Listener above App widget is the best approach I've found:
Listener(
onPointerUp: (_) {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) {
currentFocus.focusedChild.unfocus();
}
},
child: MaterialApp(
title: 'Flutter Test App',
theme: theme,
...
),
)
This may simplify the case. Below code will work only if keyboard is open
if(FocusScope.of(context).isFirstFocus) {
FocusScope.of(context).requestFocus(new FocusNode());
}
As in Flutter everything is a widget, I decided to wrap the FocusScope.of(context).unfocus(); approach in a short utility widget.
Just create the KeyboardHider widget:
import 'package:flutter/widgets.dart';
/// A widget that upon tap attempts to hide the keyboard.
class KeyboardHider extends StatelessWidget {
/// Creates a widget that on tap, hides the keyboard.
const KeyboardHider({
required this.child,
Key? key,
}) : super(key: key);
/// The widget below this widget in the tree.
final Widget child;
#override
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => FocusScope.of(context).unfocus(),
child: child,
);
}
}
Now, you can wrap any widget (very convenient when using a good IDE) with the KeyboardHider widget, and then when you tap on something, the keyboard will close automatically. It works well with forms and other tappable areas.
class SimpleWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return KeyboardHider(
/* Here comes a widget tree that eventually opens the keyboard,
* but the widget that opened the keyboard doesn't necessarily
* takes care of hiding it, so we wrap everything in a
* KeyboardHider widget */
child: Container(),
);
}
}
You can use unfocus() method from FocusNode class.
import 'package:flutter/material.dart';
class MyHomePage extends StatefulWidget {
MyHomePageState createState() => new MyHomePageState();
}
class MyHomePageState extends State<MyHomePage> {
TextEditingController _controller = new TextEditingController();
FocusNode _focusNode = new FocusNode(); //1 - declare and initialize variable
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(),
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.send),
onPressed: () {
_focusNode.unfocus(); //3 - call this method here
},
),
body: new Container(
alignment: FractionalOffset.center,
padding: new EdgeInsets.all(20.0),
child: new TextFormField(
controller: _controller,
focusNode: _focusNode, //2 - assign it to your TextFormField
decoration: new InputDecoration(labelText: 'Example Text'),
),
),
);
}
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new MyHomePage(),
);
}
}
void main() {
runApp(new MyApp());
}
To summarize, this is a working solution for Flutter 1.17:
Wrap your Widget like this:
GestureDetector(
onTap: FocusScope.of(context).unfocus,
child: YourWidget(),
);
if you use CustomScrollView, just put,
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
You can wrap your widget with "GestureDetector", then assign "FocusScope.of(context).unfocus()" to its onTap function
GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: child,
);
_dismissKeyboard(BuildContext context) {
FocusScope.of(context).requestFocus(new FocusNode());
}
#override
Widget build(BuildContext context) {
return new GestureDetector(
onTap: () {
this._dismissKeyboard(context);
},
child: new Container(
color: Colors.white,
child: new Column(
children: <Widget>[/*...*/],
),
),
);
}
Call this function when you needed
void hideKeyboard(BuildContext context) {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) {
FocusManager.instance.primaryFocus?.unfocus();
}
}
You can also declare a focusNode for you textfield and when you are done you can just call the unfocus method on that focusNode
and also dispose it
class MyHomePage extends StatefulWidget {
MyHomePageState createState() => new MyHomePageState();
}
class MyHomePageState extends State<MyHomePage> {
TextEditingController _controller = new TextEditingController();
/// declare focus
final FocusNode _titleFocus = FocusNode();
#override
void dispose() {
_titleFocus.dispose();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(),
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.send),
onPressed: () {
setState(() {
// send message
// dismiss on screen keyboard here
_titleFocus.unfocus();
_controller.clear();
});
},
),
body: new Container(
alignment: FractionalOffset.center,
padding: new EdgeInsets.all(20.0),
child: new TextFormField(
controller: _controller,
focusNode: _titleFocus,
decoration: new InputDecoration(labelText: 'Example Text'),
),
),
);
}
}
FocusScope.of(context).unfocus() has a downside when using with filtered listView.
Apart from so many details and concisely, use keyboard_dismisser package in https://pub.dev/packages/keyboard_dismisser will solve all the problems.
I have created this function to my base code, so far works well!!
void hideKeyword(BuildContext context) {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) {
currentFocus.focusedChild.unfocus();
}
}
FocusScope.of(context).unfocus(); doesn't work.
This code works for me at flutter ver 2.2.3 and null safety.
WidgetsBinding.instance?.focusManager.primaryFocus?.unfocus()
Source: https://github.com/flutter/flutter/issues/20227#issuecomment-512860882
For example, put this code in MyAppState to apply hide keyboard when touch outside for whole app.
return GestureDetector(
onTap: () =>
WidgetsBinding.instance?.focusManager.primaryFocus?.unfocus(),
child: MaterialApp(
title: 'Flutter Demo',
theme: getTheme(),
home: _body(),
),
);
Use SystemChannels.textInput.invokeMethod('TextInput.hide');. It will close/dismiss the keyboard when the screen loads.
void initState() {
super.initState();
SystemChannels.textInput.invokeMethod('TextInput.hide');
}
====== Dismiss the keyboard after clicking out of the TextField =======
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(), //this will dismiss keyboard
child: Scaffold(
body: SafeArea(
.........
====== Dismiss the keyboard when scrolling the screen =======
ListView(
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, //this will dismiss
children: [
..........
The SingleChildScrollView widget also have this property.
You can use this one.
FocusScope.of(context).requestFocus(FocusNode());
And you can use this onTap of GestureDetector or InkWell like this.
`GestureDetector(
onTap: () {`
// THIS FOCUS SCOPE WILL CLOSE THE KEYBOARD
FocusScope.of(context).requestFocus(FocusNode());
forgotPasswordAPI(emailController.text);
},``
add this code inside build widget
FocusScope.of(context).requestFocus(FocusNode());
If your keyboard still won't turn off , don't forget add focusNode to TextField. The above information was helpful, but forgetting to add focusNode bothered me a bit. Here an example.
TextField(
focusNode: FocusNode(),
textController: _controller,
autoFocus: false,
textStyle: TextStyle(fontSize: 14),
onFieldSubmitted: (text) {},
onChanged: (text) {},
hint: 'Enter the code',
hintColor: CustomColors.mediumGray,
suffixAsset: _voucherController.text.length == 7
? Assets.ic_approved_voucher
: null,
isIcon: false,
isObscure: false,
maxLength: 7,
)
closeKeyboard(BuildContext context) {
var currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
}
#override
Widget build(BuildContext context) {
_keyboardVisible = MediaQuery.of(context).viewInsets.bottom != 0;
size = MediaQuery.of(context).size;
return GestureDetector(
onTap: () {
closeKeyboard(context);
},
child: Scaffold(
backgroundColor: Colors.white,
body: Container(
width: double.maxFinite,
height: double.maxFinite,
child: _buildUI(vm)),
),
);
}
try using a TextEditingController.
at the begining,
final myController = TextEditingController();
#override
void dispose() {
// Clean up the controller when the widget is disposed.
myController.dispose();
super.dispose();
}
and in the on press event,
onPressed: () {
myController.clear();}
this will dismiss the keybord.
If you use TextField(maxLines: null) and just want to show Done button ON the screen keyboard to hide it, the code below works.
TextField(
keyboardType: TextInputType.text,
maxLines: null,
)
Side note: why in the first place doesn't the keyboard show Done button? The reason is found in the implementation of TextField:
keyboardType = keyboardType ?? (maxLines == 1 ? TextInputType.text : TextInputType.multiline),

Categories

Resources