Today we will explore how to make a custom label above the text field whose style will change according to your tap on the text field/text form field. So that user can easily understand which text field is currently active.
Example:
In this, there are two fields, the first is email and the second is password. Currently, you easily understand that the email field is active and I am writing in that field because it is highlighting. But what if the email field is not highlighted even when you are typing in it? You can do this easily using text field input decorations property like this but what if you want to make a custom label for the text field You can do these with a few steps.
1. Create Stateful Widgets
Dart
import 'package:flutter/material.dart' ;
class CustomLabel extends StatefulWidget {
const CustomLabel({
Key ? key
}): super(key: key);
@override
State < CustomLabel > createState() => _CustomLabelState();
}
class _CustomLabelState extends State < CustomLabel > {
@override
Widget build(BuildContext context) {
return const Scaffold();
}
}
|
2. Create a variable as of the Focus node, bool
Single Textfield
final FocusNode focusNode = FocusNode(); // focusnode for textfield
bool isFocus = false; // local variable
Multiple Fields
final FocusNode focusNode1 = FocusNode();
final FocusNode focusNode2 = FocusNode();
final FocusNode focusNode3 = FocusNode();
// Different focus nodes for different different textfield
final Map<String, bool> _focusUnfocus = {
"focus_node_1": false,
"focus_node_2": false,
"focus_node_3": false,
};
3. In the init state add Listener to the focus node and change the bool variable value depending upon whether the text field is tapped or not.
Single Text Field
@override
void initState() {
super.initState();
// Add listener to textfield to change variable value depending upon it has focus or not
focusNode.addListener(() {
if (focusNode.hasFocus) {
isFocus = true;
} else {
isFocus = false;
}
setState(() {});
});
}
Multi TextField
// Add listener to textfield to change variable value in map depending upon it has focus or not
addListenerToNode(FocusNode focusNode, String key) {
focusNode.addListener(() {
if (focusNode.hasFocus) {
_focusUnfocus[key] = true;
} else {
_focusUnfocus[key] = false;
}
setState(() {});
});
}
@override
void initState() {
super.initState();
addListenerToNode(focusNode1, "focus_node_1");
addListenerToNode(focusNode2, "focus_node_2");
addListenerToNode(focusNode3, "focus_node_3");
}
4. Made and label of your choice just add color in that label text style on a condition like this.
Single text field
Text(
"Single Text Field",
style: TextStyle(color: isFocus ? Colors.blue : Colors.grey),
), // Condition to change color depending upon textfield has focus or not
Multiple text field
Dart
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(18.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
getLabel(
title: "Multiple Text Field 1" ,
key: "focus_node_1" ,
),
TextFormField(
focusNode: focusNode1,
),
getLabel(
title: "Multiple Text Field 2" ,
key: "focus_node_2" ,
),
TextFormField(
focusNode: focusNode2,
),
getLabel(
title: "Multiple Text Field 3" ,
key: "focus_node_3" ,
),
TextFormField(
focusNode: focusNode3,
),
],
),
),
);
}
Widget getLabel({required String title, required String key}) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
title, style: TextStyle(
color: _focusUnfocus[key] ? ? false ? Colors.blue : Colors.grey
)),
);
}
|
5. Add that focus node to your text field
TextFormField(
focusNode: focusNode,
),
// Add focusnode in textformfield/textfield
Single Textfield
Dart
import 'package:flutter/material.dart' ;
class CustomLabel extends StatefulWidget {
const CustomLabel({
Key ? key
}): super(key: key);
@override
State < CustomLabel > createState() => _CustomLabelState();
}
class _CustomLabelState extends State < CustomLabel > {
final FocusNode focusNode = FocusNode();
bool isFocus = false ;
@override
void initState() {
super.initState();
focusNode.addListener(() {
if (focusNode.hasFocus) {
isFocus = true ;
} else {
isFocus = false ;
}
setState(() {});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(18.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Single Text Field" ,
style: TextStyle(color: isFocus ? Colors.blue : Colors.grey),
),
TextFormField(
focusNode: focusNode,
),
],
),
),
);
}
}
|
Multi TextField
Dart
import 'package:flutter/material.dart' ;
class CustomLabel extends StatefulWidget {
const CustomLabel({
Key ? key
}): super(key: key);
@override
State < CustomLabel > createState() => _CustomLabelState();
}
class _CustomLabelState extends State < CustomLabel > {
final FocusNode focusNode1 = FocusNode();
final FocusNode focusNode2 = FocusNode();
final FocusNode focusNode3 = FocusNode();
final Map < String,
bool > _focusUnfocus = {
"focus_node_1" : false ,
"focus_node_2" : false ,
"focus_node_3" : false ,
};
@override
void initState() {
super.initState();
addListenerToNode(focusNode1, "focus_node_1" );
addListenerToNode(focusNode2, "focus_node_2" );
addListenerToNode(focusNode3, "focus_node_3" );
}
addListenerToNode(FocusNode focusnode, String key) {
focusnode.addListener(() {
if (focusnode.hasFocus) {
_focusUnfocus[key] = true ;
} else {
_focusUnfocus[key] = false ;
}
setState(() {});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(18.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
getLabel(
title: "Multiple Text Field 1" ,
key: "focus_node_1" ,
),
TextFormField(
focusNode: focusNode1,
),
getLabel(
title: "Multiple Text Field 2" ,
key: "focus_node_2" ,
),
TextFormField(
focusNode: focusNode2,
),
getLabel(
title: "Multiple Text Field 3" ,
key: "focus_node_3" ,
),
TextFormField(
focusNode: focusNode3,
),
],
),
),
);
}
Widget getLabel({
required String title,
required String key
}) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(title,
style: TextStyle(
color: _focusUnfocus[key] ? ? false ? Colors.blue : Colors.grey)),
);
}
}
|
Please Login to comment...