Open caduandrade opened 1 year ago
Hi @caduandrade, thanks for filing the issue.
I think this is working as intended. You are wrapping TextField
by a Container
which has color changing by invoking setState
. It looks like you click outside TextField
to unfocus
it.
Please look at my below sample to see this more clearly:
Do you agree with above explanation?
Hi @huycozy !
Unfortunately, I do not agree. :grimacing:
I used the delay just to show that the cursor was visible before disappearing.
I understood the problem because I'm a developer, but it would still be a bug for a user.
The problem occurs by clicking on TextField. The first and only click is on the TextField and it doesn't show the cursor.
The same problem occurs when typing in the TextField.
Note that in both cases the user did not click away.
Maybe it's difficult to solve with the current architecture but as I said, for the user this would be a bug. I'm a developer and it took me a while to figure out that the problem was setting the color.
Thank you very much!
import 'package:flutter/material.dart';
void main() {
runApp(const ExampleApp());
}
class ExampleApp extends StatelessWidget {
const ExampleApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Clicking',
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final FocusNode _focusNode = FocusNode();
final TextEditingController _controller = TextEditingController();
Color? _color;
@override
void initState() {
super.initState();
_focusNode.addListener(_onFocusChanged);
}
void _onFocusChanged() {
setState(() {
print('focus changed: ${_focusNode.hasFocus}');
_color = _focusNode.hasFocus ? Colors.green[200] : null;
});
}
@override
void dispose() {
_focusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
// setState + color = TextField cursor gone
color: _color,
child: Center(
child: SizedBox(
width: 150,
child: TextField(
focusNode: _focusNode, controller: _controller)))));
}
}
import 'package:flutter/material.dart';
void main() {
runApp(const ExampleApp());
}
class ExampleApp extends StatelessWidget {
const ExampleApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Typing',
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final TextEditingController _controller = TextEditingController();
Color? _color;
@override
void initState() {
super.initState();
_controller.addListener(_onType);
}
void _onType() {
Color? color = _controller.text.isNotEmpty ? Colors.green[200] : null;
if (_color != color) {
setState(() {
_color = color;
});
}
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
// setState + color = TextField cursor gone
color: _color,
child: Center(
child: SizedBox(
width: 150, child: TextField(controller: _controller)))));
}
}
Hi @caduandrade, Thanks for filing the issue. That is really a strange behavior, unfortunately, I do not have a reasoning for that. I am labeling this issue for further insights from the team. The issue is reproducible with the above code samples. With the first code sample the textfield has focus but the cursor is not visible.
This is really interesting, I'm guessing that the setState causes the render object to update and then the field to lose focus somehow.
I noticed that there's no bug if the color change happens to a sibling widget.
I ran into a similar issue with a disappearing cursor when I found this post. In my case I had a decoration property I conditionally set to a value when the TextField was focused.
For this particular case, a work around is to use the lifecycle methods onTap
and onSubmitted
to conditionally set the color, tapping the text field will focus it and submitting it will do the opposite.
import 'package:flutter/material.dart';
void main() {
runApp(const ExampleApp());
}
class ExampleApp extends StatelessWidget {
const ExampleApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Clicking',
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final FocusNode _focusNode = FocusNode();
final TextEditingController _controller = TextEditingController();
Color? _color;
@override
void dispose() {
_focusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
// setState + color = TextField cursor gone
color: _color,
child: Center(
child: SizedBox(
width: 150,
child: TextField(
onTap: () => setState(() {
_color = Colors.green[200];
}),
onSubmitted: (value) => setState(() {
_color = Colors.white10;
}),
focusNode: _focusNode,
controller: _controller,
),
),
),
),
);
}
}
A workaround is to replace the null
color with Colors.transparent
.
This issue is assigned but has had no recent status updates. Please consider unassigning this issue if it is not going to be addressed in the near future. This allows people to have a clearer picture of what work is actually planned. Thanks!
I will fix this soon.
I am encountering a similar issue with the TextInput cursor, and I believe it may be a bug. I have a TextInput designed for password entry.
In my first attempt, when I input an incorrect password and press enter, I observe that the TextField controller clears, and the cursor remains visible.
However, in the second attempt, when I enter an incorrect password again and press enter, the TextField controller clears, but the cursor disappears.
This issue persists whether or not I use a FocusNode.
This issue is assigned to @xu-baolin but has had no recent status updates. Please consider unassigning this issue if it is not going to be addressed in the near future. This allows people to have a clearer picture of what work is actually planned. Thanks!
@xu-baolin , please fix this issue or inform the community about it so that other people can contribute
I'm just updating the background after my TextField receives focus.
The TextField lost the cursor after a Container receives a color in the setState. Only happens if the color was NULL.
The setState without set the color is ok.
Steps to Reproduce
Code
flutter doctor