【问题标题】:setState() is not changing visibilitysetState() 没有改变可见性
【发布时间】:2021-09-04 05:00:54
【问题描述】:

我正在制作一个弹出对话框,在用户进入某些屏幕时询问他的密码。该字段应该有一个更改密码可见性的图标,但没有进行状态更改,只有当我退出对话框并再次打开它时才会发生。

  getConfirmationPortalKey() {
return showGeneralDialog(
  transitionBuilder: (ctx, anim1, anim2, child) => BackdropFilter(
    filter:
        ImageFilter.blur(sigmaX: 4 * anim1.value, sigmaY: 4 * anim1.value),
    child: FadeTransition(
      child: child,
      opacity: anim1,
    ),
  ),
  context: context,
  barrierDismissible: true,
  barrierLabel: '',
  barrierColor: Colors.black26,
  transitionDuration: Duration(milliseconds: 200),
  pageBuilder: (ctx, anim1, anim2) => AlertDialog(
    content: Wrap(
      alignment: WrapAlignment.center,
      children: [
        Wrap(
          alignment: WrapAlignment.center,
          children: [
            Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [                    
                Padding(
                  padding: EdgeInsets.only(top: 10, bottom: 10),
                  child: TextField(
                    decoration: InputDecoration(
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.all(
                          Radius.circular(10),
                        ),
                      ),
                      hintText: 'Input Password',
                      suffixIconConstraints:
                          BoxConstraints.tightFor(height: 50, width: 50),
                      suffixIcon: Padding(
                        padding: EdgeInsets.only(top: 5),
                        child: SizedBox(
                          width: 24,
                          height: 24,
                          child: IconButton(
                            icon: passwordPortalVisible
                                ? SvgPicture.asset(
                                    "assets/svgs/icons/visibility_off.svg",
                                    fit: BoxFit.scaleDown,
                                    color: widget.colors.grey.shade400,
                                  )
                                : SvgPicture.asset(
                                    "assets/svgs/icons/visibility_on.svg",
                                    fit: BoxFit.scaleDown,
                                    color: widget.colors.grey.shade400,
                                  ),
                            onPressed: passwordVisible
                                ? null
                                : () {
                                    setState(() {
                                      passwordVisible =
                                          !passwordVisible;
                                    });
                                  },
                          ),
                        ),
                      ),
                    ),
                    controller: textEditingControllerKey,
                    keyboardType: TextInputType.number,
                    obscureText: !passwordVisible,
                  ),
                ),
              ],
            ),
          ],
        ),
    Padding(
              padding:
                  EdgeInsets.only(left: 30, right: 30, top: 10, bottom: 10),
              child: Row(
                children: [
                  Expanded(
                  widget._myBtns.elevatedButton('OK

', (){UserLogin 用户 = UserLogin();}) ), ], ), ), ), ], ), ); }

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    我认为您需要在AlertDialog 中使用StatefulBuilder。我认为这是因为对话框是一个叠加层,不知道它来自哪个小部件。

    https://api.flutter.dev/flutter/widgets/StatefulBuilder-class.html

    以下是您编辑的代码:

     getConfirmationPortalKey() {
    return showGeneralDialog(
      transitionBuilder: (ctx, anim1, anim2, child) => BackdropFilter(
        filter:
            ImageFilter.blur(sigmaX: 4 * anim1.value, sigmaY: 4 * anim1.value),
        child: FadeTransition(
          child: child,
          opacity: anim1,
        ),
      ),
      context: context,
      barrierDismissible: true,
      barrierLabel: '',
      barrierColor: Colors.black26,
      transitionDuration: Duration(milliseconds: 200),
      pageBuilder: (ctx, anim1, anim2) => AlertDialog(
        content: StatefulBuilder(
            builder: (BuildContext context, StateSetter setDialogState) {
    
              bool passwordVisible = false;
     
             return Wrap(
          alignment: WrapAlignment.center,
          children: [
            Wrap(
              alignment: WrapAlignment.center,
              children: [
                Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [                    
                    Padding(
                      padding: EdgeInsets.only(top: 10, bottom: 10),
                      child: TextField(
                        decoration: InputDecoration(
                          border: OutlineInputBorder(
                            borderRadius: BorderRadius.all(
                              Radius.circular(10),
                            ),
                          ),
                          hintText: 'Input Password',
                          suffixIconConstraints:
                              BoxConstraints.tightFor(height: 50, width: 50),
                          suffixIcon: Padding(
                            padding: EdgeInsets.only(top: 5),
                            child: SizedBox(
                              width: 24,
                              height: 24,
                              child: IconButton(
                                icon: passwordPortalVisible
                                    ? SvgPicture.asset(
                                        "assets/svgs/icons/visibility_off.svg",
                                        fit: BoxFit.scaleDown,
                                        color: widget.colors.grey.shade400,
                                      )
                                    : SvgPicture.asset(
                                        "assets/svgs/icons/visibility_on.svg",
                                        fit: BoxFit.scaleDown,
                                        color: widget.colors.grey.shade400,
                                      ),
                                onPressed:() => setDialogState(() {
                                          passwordVisible =
                                              !passwordVisible;
                                        });
                                     
                              ),
                            ),
                          ),
                        ),
                        controller: textEditingControllerKey,
                        keyboardType: TextInputType.number,
                        obscureText: !passwordVisible,
                      ),
                    ),
                  ],
                ),
              ],
            ),
        Padding(
                  padding:
                      EdgeInsets.only(left: 30, right: 30, top: 10, bottom: 10),
                  child: Row(
                    children: [
                      Expanded(
                      widget._myBtns.elevatedButton('OK
    

    【讨论】:

    • 我在“onPressed”中遇到错误。此表达式的类型为“void”,因此无法使用其值。
    • 对不起,我的错,将 onPressed 更改为 () => setDialogState ...。我将编辑我的答案
    【解决方案2】:

    问题出在这一行:

    onPressed: passwordVisible ? null : () {...}
    

    您的 onPressed 事件仅在 passwordVisible 为 false 时调用该函数。去掉三元运算符,不管passwordVisible是真还是假都会调用:

    onPressed: () {...}
    

    【讨论】:

    • 没有用。我是这样做的: onPressed: passwordVisible ? null : () {setState(() {passwordVisible = !passwordVisible;});},
    • 还是一样的问题,试试onPressed: () {...}(不用三元算子检查passwordVisible)
    猜你喜欢
    • 2011-04-10
    • 2012-04-07
    • 2017-04-29
    • 2012-03-07
    • 2021-07-19
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    • 2012-06-27
    相关资源
    最近更新 更多