【问题标题】:Flutter : how to conditionally repeat a showDialog inside a ListViewFlutter:如何有条件地在 ListView 中重复 showDialog
【发布时间】:2021-05-19 14:35:47
【问题描述】:

我正在使用 flutter_reactive_ble_example 通过修改文件 device_list.dart 来连接到我的蓝牙模块。

我想知道如果密码错误,我该如何重新提示用户。

我是 Flutter 的新手,如果需要,请询问更多详细信息。

这是我目前拥有的代码 sn-p:

Flexible(
child: ListView(
  children: widget.scannerState.discoveredDevices
      .map(
        (device) => ListTile(
          title: Text(tile.name),
          subtitle: Text("${tile.name}\n: ${tile.sub}"),
          leading: const ConnectIcon(),
          onTap: () async {
            //stop the scan
            widget.stopScan();
            //connect to the device
            await widget.deviceConn.connect(device.id);
            //prompt user for password              
            final inputData = await showDialog(
              context: context,
              barrierDismissible:
                  false, // prevent user from closing the dialog by pressing outside the dialog
              builder: (_) {
                String userData = "";
                return AlertDialog(
                  title: new Text("Enter Password"),
                  content: new TextField(
                    onChanged: (value) {
                      userData = value;
                    },
                  ),
                  actions: <Widget>[
                    ElevatedButton(
                      child: Text('Ok'),
                      onPressed: () async {
                        //on press subscribe and send the password
                        response = await ble.subscribeToCharacteristic(characteristic);

                        //if data failure check, how do I reshow this showDialog??
                        response.listen((event) {
                            if(event == 1){
                              //if return 1, password correct 
                              Navigator.of(context).pop(userData);
                            }else{                                  
                              //if not reshow Dialog
                              //howw?
                            }                                                                
                        }
                        
                        //send password
                        ble.writeCharacteristicWithoutResponse(characteristic, value: userData);
                      },
                    )
                  ],
                );
              },
            );

            Navigator.of(context).pop(
                inputData); // pass data back to the previous page
          },
        ),
      )
      .toList(),
),
),
      

【问题讨论】:

    标签: flutter bluetooth-lowenergy flutter-layout


    【解决方案1】:

    我认为你可以使用递归,这里是一个例子

    Future _showPasswordDialog(){
     return showDialog(
                  context: context,
                  barrierDismissible:
                      false, // prevent user from closing the dialog by pressing outside the dialog
                  builder: (_) {
                    String userData = "";
                    return AlertDialog(
                      title: new Text("Enter Password"),
                      content: new TextField(
                        onChanged: (value) {
                          userData = value;
                        },
                      ),
                      actions: <Widget>[
                        ElevatedButton(
                          child: Text('Ok'),
                          onPressed: () async {
                            //on press subscribe and send the password
                            response = await ble.subscribeToCharacteristic(characteristic);
    
                            //if data failure check, how do I reshow this showDialog??
                            response.listen((event) {
                                if(event == 1){
                                  //if return 1, password correct 
                                  Navigator.of(context).pop(userData);
                                }else{                                  
                                  //if not reshow Dialog
                                  //howw?
                                 Navigator.of(context).pop();
                                 _showPasswordDialog();
                               }                                                                
                            }
                            
                            //send password
                            ble.writeCharacteristicWithoutResponse(characteristic, value: userData);
                          },
                        )
                      ],
                    );
                  },
                );
    }
    

    【讨论】:

      【解决方案2】:

      将alert提示分离为另一个函数,如果登录成功则返回用户详细信息,否则返回null。

      Future<String> promptAlert(BuildContext context){
      
       return showDialog(
                    context: context,
                    barrierDismissible:
                        false, // prevent user from closing the dialog by pressing outside the dialog
                    builder: (_) {
                      String userData = "";
                      return AlertDialog(
                        title: new Text("Enter Password"),
                        content: new TextField(
                          onChanged: (value) {
                            userData = value;
                          },
                        ),
                        actions: <Widget>[
                          ElevatedButton(
                            child: Text('Ok'),
                            onPressed: () async {
                              //on press subscribe and send the password
                              response = await ble.subscribeToCharacteristic(characteristic);
      
                              //if data failure check, how do I reshow this showDialog??
                              response.listen((event) {
                                  if(event == 1){
                                    //if return 1, password correct 
                                    Navigator.of(context).pop(userData);
                                  }else{                                  
                                     Navigator.of(context).pop();
                                  }                                                                
                              }
                              
                              //send password
                              ble.writeCharacteristicWithoutResponse(characteristic, value: userData);
                            },
                          )
                        ],
                      );
                    },
                  );
      
      }
      

      并检查 ListItem onTap 上的返回值是否为空

      bool isLogin = (await promptAlert(context)) !=null;
      while(isLogin ){
                 ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                 duration: Duration(seconds: 2),
                 content: Text('Login Failed Try again')));
                 String user= await Future.delayed(
                        Duration(seconds: 2), () => promptAlert(context));
       isLogin =  user !=null;
      }
      

      如果您想显示小吃店和延迟警报,

                        ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                          duration: Duration(seconds: 2),
                          content: Text('Login Failed Try again'),
                        ));
                        Future.delayed(
                            Duration(seconds: 2), () => promptAlert(context));
                    
      

      【讨论】:

      • 嗨,我想添加一个延迟几秒钟的小吃店并重新提示?
      • 你可以在提示前使用snack,即在循环内。
      • 我在 isUnlocked = (await promptAlert(context)....小吃吧几秒钟,然后重新提示?
      • 您可以使用 Future 延迟显示提示。我已经更新了代码。
      • 在您更新的代码中,您使用了 Future 和 String user = ...,但返回的类型是 showdialog(...) 这可能吗?由于返回类型不是字符串,那不会引发错误吗?
      猜你喜欢
      • 2019-10-24
      • 2020-09-16
      • 2020-04-10
      • 2020-02-11
      • 1970-01-01
      • 1970-01-01
      • 2019-11-26
      • 1970-01-01
      • 2020-03-02
      相关资源
      最近更新 更多