Dart 为http POST请求从颤振上的TextFormField捕获数据

Dart 为http POST请求从颤振上的TextFormField捕获数据,dart,flutter,Dart,Flutter,我正在尝试使用Flatter登录。 我正在咨询一家网络服务公司。 我想在Post请求的正文中发送来自不同TextFormField的用户名和密码。我该怎么做? 这是我一直在编写的代码 import 'package:flutter/material.dart'; import 'package:device_id/device_id.dart'; import 'package:http/http.dart' as http; import 'dart:async'; import 'dart

我正在尝试使用Flatter登录。 我正在咨询一家网络服务公司。 我想在Post请求的正文中发送来自不同TextFormField的用户名和密码。我该怎么做? 这是我一直在编写的代码

import 'package:flutter/material.dart';
import 'package:device_id/device_id.dart';
import 'package:http/http.dart' as http;

import 'dart:async';
import 'dart:convert';


class SignIn extends StatefulWidget {
  @override
  _SignInState createState() => _SignInState();
}

class _SignInState extends State<SignIn> {
  Future<String> getData() async {
    final response = await http.post(
        Uri.encodeFull("The route i'm consulting),
        body: {
          "username": user,
          "password": password
        },
这是我要检索的第一个TextFormField,以便在请求正文中发送它

      controller: controller,
      keyboardType: TextInputType.text,
      autofocus: false,
      decoration: InputDecoration(
          hintText: "Username",
          hintStyle: TextStyle(fontSize: 16.0),
          contentPadding: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 10.0),
          border:
              UnderlineInputBorder(borderRadius: BorderRadius.circular(32.0))),
    );
    final password = TextFormField(
      controller: controller2,
      autofocus: false,
      obscureText: true,
      decoration: InputDecoration(
          hintText: "Password",
          hintStyle: TextStyle(fontSize: 16.0),
          contentPadding: EdgeInsets.fromLTRB(20.0, 25.0, 20.0, 10.0),
          border:
              UnderlineInputBorder(borderRadius: BorderRadius.circular(32.0))),
    );

    final loginButton = Padding(
      padding: EdgeInsets.symmetric(vertical: 25.0),
      child: Material(
        borderRadius: BorderRadius.circular(30.0),
        shadowColor: Colors.blueAccent.shade100,
        elevation: 10.0,
        child: MaterialButton(
          minWidth: 200.0,
          height: 42.0,
          color: Colors.blueAccent,
          onPressed: (){

          },
          child: Text(
            "Login",
            style: TextStyle(color: Colors.white),
          ),
        ),
      ),
    );

    return Form(
      child: new Center(
        child: ListView(
            padding: EdgeInsets.only(left: 24.0, right: 24.0, top: 10.0),
            children: <Widget>[
              username,
              SizedBox(height: 8.0),
              password,
              SizedBox(height: 24.0),
              loginButton
            ]),
      ),
    );
  }
}
这是我想要检索的第二个TextFormField,以便在请求体中发送它

      controller: controller,
      keyboardType: TextInputType.text,
      autofocus: false,
      decoration: InputDecoration(
          hintText: "Username",
          hintStyle: TextStyle(fontSize: 16.0),
          contentPadding: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 10.0),
          border:
              UnderlineInputBorder(borderRadius: BorderRadius.circular(32.0))),
    );
    final password = TextFormField(
      controller: controller2,
      autofocus: false,
      obscureText: true,
      decoration: InputDecoration(
          hintText: "Password",
          hintStyle: TextStyle(fontSize: 16.0),
          contentPadding: EdgeInsets.fromLTRB(20.0, 25.0, 20.0, 10.0),
          border:
              UnderlineInputBorder(borderRadius: BorderRadius.circular(32.0))),
    );

    final loginButton = Padding(
      padding: EdgeInsets.symmetric(vertical: 25.0),
      child: Material(
        borderRadius: BorderRadius.circular(30.0),
        shadowColor: Colors.blueAccent.shade100,
        elevation: 10.0,
        child: MaterialButton(
          minWidth: 200.0,
          height: 42.0,
          color: Colors.blueAccent,
          onPressed: (){

          },
          child: Text(
            "Login",
            style: TextStyle(color: Colors.white),
          ),
        ),
      ),
    );

    return Form(
      child: new Center(
        child: ListView(
            padding: EdgeInsets.only(left: 24.0, right: 24.0, top: 10.0),
            children: <Widget>[
              username,
              SizedBox(height: 8.0),
              password,
              SizedBox(height: 24.0),
              loginButton
            ]),
      ),
    );
  }
}
控制器:控制器2,
自动对焦:错误,
蒙昧文字:对,
装饰:输入装饰(
hintText:“密码”,
hintStyle:TextStyle(fontSize:16.0),
内容填充:来自LTRB(20.0,25.0,20.0,10.0)的EdgeInsets,
边界:
UnderlineInputBorder(borderRadius:borderRadius.circular(32.0)),
);
最终登录按钮=填充(
填充:边缘组。对称(垂直:25.0),
儿童:材料(
边界半径:边界半径。圆形(30.0),
shadowColor:Colors.blueAccent.shade100,
标高:10.0,
子:材质按钮(
最小宽度:200.0,
身高:42.0,
颜色:Colors.blueAccent,
已按下:(){
},
子:文本(
“登录”,
样式:TextStyle(颜色:Colors.white),
),
),
),
);
报税表(
孩子:新中心(
子:ListView(
填充:仅限边缘设置(左侧:24.0,右侧:24.0,顶部:10.0),
儿童:[
用户名,
尺寸箱(高度:8.0),
密码,
尺寸箱(高度:24.0),
登录按钮
]),
),
);
}
}
请参阅

  • 在表单周围包装一个
    StatefulWidget
  • 在您的
    状态中添加两个
    TextEditingController
    字段,每个
    TextFormField
  • 将控制器传递给表单字段(
    controller
    constructor参数)
  • 检索值,例如在按钮单击侦听器中使用
    myController.text
  • 我不确定您是否也在询问如何发送HTTP post请求

    以下是一个非常简单的示例:

    class LoginScreen extends StatefulWidget {
      @override
      State<StatefulWidget> createState() => _LoginScreenState();
    }
    
    class _LoginScreenState extends State<LoginScreen> {
    
      final _usernameController = TextEditingController();
      final _passwordController = TextEditingController();
    
      @override
      Widget build(BuildContext context) {
        return Column(
          children: <Widget>[
            TextFormField(controller: _usernameController,),
            TextFormField(controller: _passwordController, obscureText: true,),
            RaisedButton(
              onPressed: _performLogin,
              child: Text('Login'),
            )
          ],
        );
      }
    
      void _performLogin() {
        String username = _usernameController.text;
        String password = _passwordController.text;
    
        print('login attempt: $username with $password');
      }
    }
    
    class LoginScreen扩展StatefulWidget{
    @凌驾
    State createState()=>\u LoginScreenState();
    }
    类_LoginScreenState扩展状态{
    final _usernameController=TextEditingController();
    final _passwordController=TextEditingController();
    @凌驾
    小部件构建(构建上下文){
    返回列(
    儿童:[
    TextFormField(控制器:_usernameController,),
    TextFormField(controller:_passwordController,obscureText:true,),
    升起的按钮(
    按下按钮:_performLogin,
    子项:文本('Login'),
    )
    ],
    );
    }
    void _performLogin(){
    字符串username=\u usernameController.text;
    字符串密码=_passwordController.text;
    打印('登录尝试:$username with$password');
    }
    }
    
    以下是登录屏幕的完整示例。。。您可以验证输入,并在通过验证后提交数据

    import 'package:flutter/material.dart';
    import '../mixins/validate_mixin.dart';
    
    class LoginScreen extends StatefulWidget{
      final GlobalKey<ScaffoldState> scaffoldKey;
      LoginScreen(this.scaffoldKey);
      @override
      State<StatefulWidget> createState() {
        return LoginScreenState(scaffoldKey);
      }
    }
    
    class LoginScreenState extends State<LoginScreen>  with ValidateMixin{
      final formKey = GlobalKey<FormState>();
      final GlobalKey<ScaffoldState> scaffoldKey;
    
      LoginScreenState(this.scaffoldKey);
    
      String _email;
      String _password;
    
      @override
      Widget build(BuildContext context) {
        return Container(
          margin: EdgeInsets.all(40.0),
          child: Form(
            key: formKey,
            child: Column(
              children: <Widget>[
                emailField(),
                passwordField(),
                Container(margin: EdgeInsets.only(bottom: 25.0),),
                submitButton(),
              ],
            ),
          ),
        );
      }
    
      Widget emailField() {
        return TextFormField(
          decoration: InputDecoration(hintText: 'ali@gmail.co', labelText: 'Email'),
          keyboardType: TextInputType.emailAddress,
          validator: validateEmail,
          onSaved: (String value) {
            _email = value;
          },
        );
      }
    
      Widget passwordField() {
        return TextFormField(
          obscureText: true,
          decoration: InputDecoration(hintText: '*****', labelText: 'Password'),
          onSaved: (String value) {
            _password = value;
          },
        );
      }
    
      Widget submitButton() {
        return RaisedButton.icon(
          color: Colors.cyan[900],
          textColor: Colors.white,
          label: Text('Submit'),
          icon: Icon(Icons.save), 
          onPressed: () {
            final bool v = formKey.currentState.validate();
            if (v) {
              formKey.currentState.save();
              _performLogin();
              print('object');
            }
        },);
      }
    
      void _performLogin () {
        var snackbar = new SnackBar(
          content: Text('Email: $_email and Password $_password'),
        );
        scaffoldKey.currentState.showSnackBar(snackbar);
      }
    }
    
    导入“包装:颤振/材料.省道”;
    导入“../mixin/validate_mixin.dart”;
    类LoginScreen扩展StatefulWidget{
    最终GlobalKey脚手架钥匙;
    LoginScreen(this.scaffoldKey);
    @凌驾
    状态createState(){
    返回登录筛选状态(scaffoldKey);
    }
    }
    类LoginScreenState使用ValidateMixin扩展状态{
    final formKey=GlobalKey();
    最终GlobalKey脚手架钥匙;
    LoginsScreenState(this.scaffoldKey);
    字符串\u电子邮件;
    字符串\u密码;
    @凌驾
    小部件构建(构建上下文){
    返回容器(
    边距:所有边缘集(40.0),
    孩子:表格(
    key:formKey,
    子:列(
    儿童:[
    emailField(),
    passwordField(),
    容器(边距:仅限边集(底部:25.0)),
    submitButton(),
    ],
    ),
    ),
    );
    }
    Widget emailField(){
    返回TextFormField(
    装饰:输入装饰(hintText:'ali@gmail.co,labelText:“电子邮件”),
    键盘类型:TextInputType.emailAddress,
    验证器:validateEmail,
    onSaved:(字符串值){
    _电子邮件=价值;
    },
    );
    }
    小部件密码字段(){
    返回TextFormField(
    蒙昧文字:对,
    装饰:输入装饰(hintText:'*****',labelText:'密码'),
    onSaved:(字符串值){
    _密码=值;
    },
    );
    }
    小部件提交按钮(){
    返回RaisedButton.icon(
    颜色:颜色。青色[900],
    textColor:Colors.white,
    标签:文本(“提交”),
    图标:图标(Icons.save),
    已按下:(){
    final bool v=formKey.currentState.validate();
    如果(v){
    formKey.currentState.save();
    _performLogin();
    打印(“对象”);
    }
    },);
    }
    void _performLogin(){
    var snackbar=新snackbar(
    内容:文本(“电子邮件:$\电子邮件和密码$\密码”),
    );
    scaffoldKey.currentState.showSnackBar(snackbar);
    }
    }
    
    您可以回到完整的示例。

    感谢您的回答,尽管我还停留在第四步,但您能否发布一个示例,以便我能够遵循它?添加了一个示例(尽管我也链接了一个示例)。有人建议在dispose()方法中对TextEditingController进行编辑。虽然处置控制器是一种良好的做法,但这并不是必需的(请查看控制器的源代码),所以我拒绝了它。如果我有一个名为LoginUI.dart的文件,我在其中放置登录UI组件,其中一个文件是另一个名为LoginEmailTextfield.dart的文件,我在其中放置LoginEmailTextfield属性,最后是一个loginBtn.dart,我在其中放置登录按钮属性,我该怎么做?LoginEmailTextfield.dart和loginBtn.dart在LoginUI.dart中导入这似乎比使用
    TextEditingController
    更简单。有