【问题标题】:How to toggle the suffix icon on the textfields separately如何分别切换文本字段上的后缀图标
【发布时间】:2021-03-04 04:30:40
【问题描述】:

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

我的文本字段 (X 3):

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

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

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

【问题讨论】:

    标签: forms flutter dart uitextfield flutter-layout


    【解决方案1】:

    您需要为每个 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];
            });
    
    

    【讨论】:

    • 我认为会有一种动态的方式来做到这一点
    • 这将是一个列表,您将只检查索引。它也是动态的。
    • 一份清单?我没有意识到这一点
    • 非常好的代码,但在 toggleList[index] 中出现错误RangeError (index): Invalid value: Valid value range is empty: 0?图标...
    【解决方案2】:

    这是因为您对所有字段都使用了一个变量 (_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),
                  )
                ),
    

    【讨论】:

      【解决方案3】:

      当您有多个 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),
                            ),
                          ),
                        ),
                      ),
                  ],
                ),
              ),
            ),
          );
        }
      }
      

      【讨论】:

      • 太棒了! List _isToggle = List.generate(3, (index) => true);
      • 是的,List.generate 很棒。我爱飞镖。
      猜你喜欢
      • 2019-09-15
      • 2012-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-22
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      相关资源
      最近更新 更多