首页 > 解决方案 > 从子组件访问值和函数

问题描述

我是 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,
            )
          ],
        )
      ],
    );
  }
}

标签: flutterdart

解决方案


更改为此,添加 SingleChildScrollView 并移动 FloatingLoginButton

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

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

var loginModel = LoginModel();

和改变

 LoginModel().loginFieldController 

 controller: loginModel.loginFieldController,

也改变

 LoginModel().login

 onPressed: loginModel.login,

在此处输入图像描述


推荐阅读