从子组件访问值和函数

时间:2019-08-14 06:41:39

标签: flutter dart

我是Flutter的新手,并且想要构建一个登录掩码。我有两个子组件,一个包含输入字段,另一个包含登录按钮。 我试图在按下按钮时调用登录功能,并从那里的输入字段中访问值。

我不确定什么是正确的解决方案,我尝试使用带有模型类的提供程序,但是,当我运行该应用程序并单击输入字段时,我的输入字段和登录按钮消失了。如果对我来说更好,我也愿意提供完全不同的解决方案。

import 'package:flutter/material.dart';

class LoginModel extends ChangeNotifier {
  final loginFieldController = TextEditingController();
  void login() {
    print(loginFieldController.value);
  }
}

class LoginState extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Container(
            padding: EdgeInsets.only(top: 15, right: 15, left: 15, bottom: 380),
            child: Stack(children: <Widget>[
              LoginContentWidget(),
              LoginHeaderWidget(),
              FloatingLoginButton(),
            ])));
  }
}

class LoginHeaderWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.only(top: 15, left: 10, right: 10),
      alignment: Alignment.topCenter,
      child: Card(
          color: Colors.lightBlue,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(10.0),
          ),
          elevation: 15,
          child: IntrinsicHeight(
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                Center(
                  child: Container(
                    alignment: Alignment.topCenter,
                    margin: EdgeInsets.only(
                        top: 10, bottom: 10, left: 40, right: 40),
                    child: Text(
                      'LOGIN',
                      style: TextStyle(
                          color: Colors.amberAccent,
                          fontWeight: FontWeight.w500,
                          fontSize: 45),
                    ),
                  ),
                )
              ],
            ),
          )),
    );
  }
}

class LoginContentWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => LoginContentWidgetState();
}

class LoginContentWidgetState extends State<LoginContentWidget> {
  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.only(top: 50),
      child: Card(
          elevation: 5,
          child: Padding(
            padding: EdgeInsets.only(left: 20, right: 20, top: 80, bottom: 70),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                TextFormField(
                  controller: LoginModel().loginFieldController,
                  decoration: InputDecoration(
                      contentPadding:
                          EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
                      hintText: 'Email'),
                ),
                TextFormField(
                  obscureText: true,
                  decoration: InputDecoration(
                      focusColor: Colors.white,
                      fillColor: Colors.white,
                      contentPadding:
                          EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
                      hintText: 'Password'),
                ),
              ],
            ),
          )),
    );
  }
}

class FloatingLoginButton extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => FloatingLoginButtonState();
}

class FloatingLoginButtonState extends State<FloatingLoginButton> {
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.end,
      children: <Widget>[
        ButtonBar(
          alignment: MainAxisAlignment.end,
          children: <Widget>[
            FloatingActionButton.extended(
              label: Text('Login'),
              onPressed: LoginModel().login,
            )
          ],
        )
      ],
    );
  }
}

2 个答案:

答案 0 :(得分:1)

对此进行更改,添加SingleChildScrollView并移动FloatingLoginButton

from abc import ABCMeta, abstrachmethod

class MainClass(metaclass=ABCMeta):
  def __init__(self, args):
    print(work)

  def do(self):
    print("Do")

  @abstractmethod
    def todo(self):
      "comment"

class A(MainClass):
  def __init__(self,args):
    super(MainClass,self).__init__()

  def todo(self):
    print("nanananananana batman!")

class B(MainClass):
  def __init__(self,args):
    super(MainClass,self).__init__()

  def todo(self):
    print("Spaghetti code!")
    self.do()

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("-variable", default=1)
    parser.add_argument("-because",default="non important")
    args = parser.parse_args()
    if args.variable == 1:
       foo = A(args)
       foo.todo()
    elif args.variable == 2:
       foo = B(args)
       foo.todo()

编辑问题2
在所有类之外声明

class LoginState extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: SingleChildScrollView(
          child: Container(
              padding: EdgeInsets.only(top: 15, right: 15, left: 15, bottom: 380),
              child: Stack(children: <Widget>[
                LoginContentWidget(),
                LoginHeaderWidget(),
               // FloatingLoginButton(),
              ])),
        )
            ,
      floatingActionButton: FloatingLoginButton(),
    )
    ;
  }
}

并更改

var loginModel = LoginModel();

 LoginModel().loginFieldController 

并更改

 controller: loginModel.loginFieldController,

 LoginModel().login

enter image description here

答案 1 :(得分:0)

在登录功能中,我从用户名文本字段打印文本。我没有收到错误,但该值为空。

  final loginFieldController = TextEditingController();
  void login() {
    print(loginFieldController.text);
  }

[![Output][1]][1]


  [1]: https://i.stack.imgur.com/36iLt.png