如何分别切换文本字段上的后缀图标

How to toggle the suffix icon on the textfields separately

我有三个通行证字段,上面有 show/hide 通行证的图标。默认的 obscureText 为 true,当用户单击图标时,它调用方法 _toggle 将模糊文本变为 false,显示 textField 内容。
但是,当用户单击该图标时,它会切换到所有 3 个文本字段,但我只想切换单击的字段。我该如何治疗?

我的文本字段 (X 3):

TextFormField(
          controller: _controller1,
          decoration: _getInputDecoration("Write your current pass"),
          keyboardType: TextInputType.text,
          obscureText: _isToggle,

我的获取输入装饰(带有手势检测器内的图标):

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,
          )
        ),

这是 _toggle 方法:

void _toggle() {
    setState(() {
      _isToggle = !_isToggle;
    });
  }

您需要为每个 TextFormField 单独的 _isToggle 变量。并仅设置点击的 TextFormField。

编辑:


  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];
        });

这是因为您对所有字段使用了一个变量 (_isToggle)。 使用 3 个独立的布尔值可以解决问题。

bool _isToggle1=false;
bool _isToggle2=false;
bool _isToggle3=false;

suffixIcon:
            Padding(
              padding: EdgeInsetsDirectional.only(end: 12.0),
              child: GestureDetector(
                child: _isToggle1 ? Icon(Icons.lock_outline_rounded, color: Colors.black,)  :
                Icon(Icons.lock_open_rounded, color: Colors.black,),
                onTap: ()=>setState(()=>_isToggle1=!_isToggle1),
              )
            ),

当你有多个TextEditingController时,请检查动态设置obscureText的代码。

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),
                      ),
                    ),
                  ),
                ),
            ],
          ),
        ),
      ),
    );
  }
}