Creating a secure and user-friendly password field is essential in mobile app development. In this tutorial, we’ll guide you on how to build a password input field with a show/hide toggle feature using Dart and Flutter, directly in Android Studio. This improves the user experience when entering complex passwords.
We’ll create a simple app UI containing a TextFormField
with an icon button that toggles the visibility of the password. The implementation is clean, efficient, and uses StatefulWidget to manage the visibility state.
Step-by-Step Guide:
1. Create a StatefulWidget for the Password Field
import 'package:flutter/material.dart';
class PasswordField extends StatefulWidget {
final <a href="https://aliendro.id/textfield-and-texteditingcontroller-guide/">TextEditingController</a> controller;
const PasswordField({super.key, required this.controller});
_PasswordFieldState createState() => _PasswordFieldState();
import 'package:flutter/material.dart';
class PasswordField extends StatefulWidget {
final <a href="https://aliendro.id/textfield-and-texteditingcontroller-guide/">TextEditingController</a> controller;
const PasswordField({super.key, required this.controller});
@override
_PasswordFieldState createState() => _PasswordFieldState();
}
import 'package:flutter/material.dart';
class PasswordField extends StatefulWidget {
final TextEditingController controller;
const PasswordField({super.key, required this.controller});
@override
_PasswordFieldState createState() => _PasswordFieldState();
}
2. Define the State and Build UI Logic
class _PasswordFieldState extends State<PasswordField> {
bool _obscureText = true;
void _toggleVisibility() {
_obscureText = !_obscureText;
Widget build(BuildContext context) {
controller: widget.controller,
obscureText: _obscureText,
decoration: InputDecoration(
border: const OutlineInputBorder(),
_obscureText ? Icons.visibility_off : Icons.visibility,
onPressed: _toggleVisibility,
class _PasswordFieldState extends State<PasswordField> {
bool _obscureText = true;
void _toggleVisibility() {
setState(() {
_obscureText = !_obscureText;
});
}
@override
Widget build(BuildContext context) {
return TextFormField(
controller: widget.controller,
obscureText: _obscureText,
decoration: InputDecoration(
labelText: 'Password',
border: const OutlineInputBorder(),
suffixIcon: IconButton(
icon: Icon(
_obscureText ? Icons.visibility_off : Icons.visibility,
),
onPressed: _toggleVisibility,
),
),
);
}
}
class _PasswordFieldState extends State<PasswordField> {
bool _obscureText = true;
void _toggleVisibility() {
setState(() {
_obscureText = !_obscureText;
});
}
@override
Widget build(BuildContext context) {
return TextFormField(
controller: widget.controller,
obscureText: _obscureText,
decoration: InputDecoration(
labelText: 'Password',
border: const OutlineInputBorder(),
suffixIcon: IconButton(
icon: Icon(
_obscureText ? Icons.visibility_off : Icons.visibility,
),
onPressed: _toggleVisibility,
),
),
);
}
}
3. Use the PasswordField Widget in Your App
class MyApp extends <a href="https://aliendro.id/create-ui-with-statelesswidget-in-dart/">StatelessWidget</a> {
const MyApp({super.key});
Widget build(BuildContext context) {
appBar: AppBar(title: const Text("Password Toggle Demo")),
padding: EdgeInsets.all(16.0),
class PasswordForm extends StatelessWidget {
const PasswordForm({super.key});
Widget build(BuildContext context) {
final TextEditingController passwordController = TextEditingController();
PasswordField(controller: passwordController),
const SizedBox(height: 20),
print('Password: ${passwordController.text}');
child: const Text('Submit'),
void main() {
runApp(const MyApp());
}
class MyApp extends <a href="https://aliendro.id/create-ui-with-statelesswidget-in-dart/">StatelessWidget</a> {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text("Password Toggle Demo")),
body: const Padding(
padding: EdgeInsets.all(16.0),
child: PasswordForm(),
),
),
);
}
}
class PasswordForm extends StatelessWidget {
const PasswordForm({super.key});
@override
Widget build(BuildContext context) {
final TextEditingController passwordController = TextEditingController();
return Column(
children: [
PasswordField(controller: passwordController),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
print('Password: ${passwordController.text}');
},
child: const Text('Submit'),
),
],
);
}
}
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text("Password Toggle Demo")),
body: const Padding(
padding: EdgeInsets.all(16.0),
child: PasswordForm(),
),
),
);
}
}
class PasswordForm extends StatelessWidget {
const PasswordForm({super.key});
@override
Widget build(BuildContext context) {
final TextEditingController passwordController = TextEditingController();
return Column(
children: [
PasswordField(controller: passwordController),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
print('Password: ${passwordController.text}');
},
child: const Text('Submit'),
),
],
);
}
}
This example makes use of standard Flutter widgets, ensuring high compatibility and simplicity. For additional Flutter input field customization, you can refer to the official Flutter TextField documentation.
Post Views: 38