How to toggle the suffix icon on the textfields separately
1,906
Solution 1
You need to seperate _isToggle variable for each TextFormField. And set only the tapped TextFormField.
EDIT:
TextEditingController _controller1 = TextEditingController();
TextEditingController _controller2 = TextEditingController();
TextEditingController _controller3 = TextEditingController();
List<bool> toggleList = List<bool>();
void _toggle(int index) {
setState(() {
toggleList[index] = !toggleList[index];
// _isToggle = !_isToggle;
});
}
List<Widget> widgetList = List<Widget>();
InputDecoration _getInputDecoration(String string, int index) {
return InputDecoration(
isDense: true,
suffixIcon: Padding(
padding: EdgeInsetsDirectional.only(end: 12.0),
child: GestureDetector(
child: toggleList[index]
? Icon(
Icons.lock_outline_rounded,
color: Colors.black,
)
: Icon(
Icons.lock_open_rounded,
color: Colors.black,
),
onTap: () {
_toggle(index);
},
),
),
);
}
addList() {
widgetList.add(TextFormField(
controller: _controller1,
decoration: _getInputDecoration("Write your current pass", 0),
keyboardType: TextInputType.text,
obscureText: toggleList[0],
));
widgetList.add(TextFormField(
controller: _controller2,
decoration: _getInputDecoration("Write your current pass", 1),
keyboardType: TextInputType.text,
obscureText: toggleList[1],
));
widgetList.add(TextFormField(
controller: _controller3,
decoration: _getInputDecoration("Write your current pass", 2),
keyboardType: TextInputType.text,
obscureText: toggleList[2],
));
}
@override
Widget build(BuildContext context) {
return ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: widgetList.length,
itemBuilder: (BuildContext context, int index) {
return widgetList[index];
});
Solution 2
Please check the code for dynamically setting the obscureText when you have multiple TextEditingController.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List _controller = List<TextEditingController>.generate(
3, (index) => TextEditingController());
List<bool> _isToggle = List<bool>.generate(3, (index) => true);
void _toggle(int index) {
setState(() {
_isToggle[index] = !_isToggle[index];
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Padding(
padding: EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
for (int i = 0; i < 3; i++)
TextFormField(
controller: _controller[i],
//decoration: _getInputDecoration("Write your current pass"),
keyboardType: TextInputType.text,
obscureText: _isToggle[i],
decoration: InputDecoration(
suffixIcon: Padding(
padding: EdgeInsetsDirectional.only(end: 12.0),
child: GestureDetector(
child: _isToggle[i]
? Icon(
Icons.lock_outline_rounded,
color: Colors.black,
)
: Icon(
Icons.lock_open_rounded,
color: Colors.black,
),
onTap: () => _toggle(i),
),
),
),
),
],
),
),
),
);
}
}
Author by
Admin
Updated on December 25, 2022Comments
-
Admin over 1 year
I have three pass fields which have icons to show/hide the pass. The default obscureText is true and when the user clicks in the icon, it calls a method _toggle that will turn the obscure text false, showing the textField content.
But, when the user clicks in the icon, it toggles to all the 3 textfields but i wanted toggle only the field clicked. How can I treat this?My text fields (X 3):
TextFormField( controller: _controller1, decoration: _getInputDecoration("Write your current pass"), keyboardType: TextInputType.text, obscureText: _isToggle,
My get input decoration (with the icon inside a Gesture detector) :
suffixIcon: Padding( padding: EdgeInsetsDirectional.only(end: 12.0), child: GestureDetector( child: _isToggle ? Icon(Icons.lock_outline_rounded, color: Colors.black,) : Icon(Icons.lock_open_rounded, color: Colors.black,), onTap: _toggle, ) ),
This is the _toggle method:
void _toggle() { setState(() { _isToggle = !_isToggle; }); }
-
Admin over 3 yearsI thought would have a dynamic way to do that
-
Akif over 3 yearsIt will be a list and you will check only the index. It is also dynamic.
-
Admin over 3 yearsA list? I'm not realising it
-
Admin over 3 yearsVery nice code, but I'm getting an error
RangeError (index): Invalid value: Valid value range is empty: 0
in the toggleList[index] ? Icon... -
Admin over 3 yearsLet us continue this discussion in chat.
-
Akif over 3 yearsThat is great! List<bool> _isToggle = List<bool>.generate(3, (index) => true);
-
bluenile over 3 yearsYep, List.generate is awesome. I love Dart.