首页 文章

具有多个类的颤动范围模型

提问于
浏览
1

我是新手,我想要管理一个具有一个文本字段的登录屏幕页面,当用户单击下一步时,我保存该值并使用范围模型状态管理将提示文本更改为同一文本字段上的下一步提示 .

首先是我的代码:

loginBase.dart(具有“登录字段(导入)”和“登录按钮”的主登录页面类):

import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:scoped_model/scoped_model.dart';
import 'login-model.dart';

//pages
import './LoginFields.dart';

class LoginPage extends StatefulWidget {
  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {

  @override
  Widget build(BuildContext context) {
    return ScopedModel<LoginModel>(
      model: LoginModel(),
      child: Scaffold(
        body: Material(
          child: Container(
            color: Colors.white,
            child: ListView(
              children: <Widget>[
                Padding(
                  padding: const EdgeInsets.only(top: 20.0, bottom: 20.0),
                  child: Image(
                      image: AssetImage("assets/images/landing_screen.jpg")),
                ),
                LoginFields(),
                Padding(
                  padding: const EdgeInsets.only(
                      left: 10.0, right: 10.0, top: 100.0),
                  child: Row(
                    children: <Widget>[
                      Expanded(
                          flex: 1,
                          child: Padding(
                            padding:
                                const EdgeInsets.only(left: 15.0, right: 15.0),
                            child: buildButton(),
                          )),
                    ],
                  ),
                )
              ],
            ),
          ),
        ),
      ),
    );
  }

  var buildButton = () => ScopedModelDescendant<LoginModel>(
        builder: (context, child, model) => FlatButton(
              onPressed: () {
                model.nextStep();
              },
              color: Colors.black,
              shape: new RoundedRectangleBorder(
                  borderRadius: new BorderRadius.circular(30.0)),
              child: Padding(
                  padding: const EdgeInsets.all(14.0),
                  child: Icon(
                    Icons.arrow_forward,
                    color: Colors.white,
                    size: 25.0,
                  )),
            ),
      );
}

LoginFields.dart(包含该字段的那个):

import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
import 'login-model.dart';

class LoginFields extends StatefulWidget {
  @override
  _LoginFieldsState createState() => _LoginFieldsState();
  LoginFields();
}

class _LoginFieldsState extends State<LoginFields> {
  @override
  Widget build(BuildContext context) {
    return ScopedModel<LoginModel>(
      model: LoginModel(),
      child: Container(
        child: Column(
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.only(left: 30.0, right: 30.0),
              child: buildTextField(),
            ),
          ],
        ),
      ),
    );
  }

  var buildTextField = () => ScopedModelDescendant<LoginModel>(
        builder: (context, child, model) => TextFormField(
              decoration: InputDecoration(
                  hintText: model.hintText,
                  enabledBorder: UnderlineInputBorder(
                      borderSide:
                          BorderSide(color: Color(0xFFE4E4E4), width: 2.0))),
              textAlign: TextAlign.center,
              controller: model.controller,
            ),
      );
}

最后是login-model.dart(包含登录页面的范围模型):

import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';

class LoginModel extends Model {
  //steps fields options
  String hintText = "How can we call you?";
  TextEditingController controller;
  int stepsCounter = 0;
  List<Step> steps = <Step>[
    Step(
        field: "username",
        controller: new TextEditingController(),
        hint: "How can we call you?"),
    Step(
        field: "email",
        controller: new TextEditingController(),
        hint: "Your Email goes here"),
    Step(
        field: "mobile",
        controller: new TextEditingController(),
        hint: "Phone number ex: +201234..."),
    Step(
        field: "password",
        controller: new TextEditingController(),
        hint: "your Password"),
  ];

  void initStep() {
    hintText = steps[0].hint;
    notifyListeners();
  }

  void nextStep() {
    if (stepsCounter <= 3) {
      steps[stepsCounter].controller=controller;
      print(controller);
      if (stepsCounter<3) {
        hintText = steps[stepsCounter + 1].hint;
      }
      stepsCounter++;
    } else {
      return;
    }
    notifyListeners();
  }
}

class Step {
  String field;
  TextEditingController controller;
  String hint;

  Step({this.field, this.controller, this.hint});
}

问题是:

当我调用 nextStep() 函数时,提示文本值在模型中发生变化但未在登录页面中更新,我是否以错误的方式应用它?

1 回答

  • 1

    我做了一些合乎逻辑的修改,但这有效,并添加了我认为您正在寻找的功能 . 问题是有一个单独的login_fields.dart类 . 该模型不与login_base.dart对话 . 我测试了这个,似乎工作得很好 .

    更新你的login_base.dart:

    import 'package:flutter/material.dart';
    import 'package:scoped_model/scoped_model.dart';
    
    import 'login_model.dart';
    
    class LoginPage extends StatelessWidget {
      TextInputType getKeyboard(StepType type) {
        switch (type) {
          case StepType.email:
            return TextInputType.emailAddress;
            break;
          case StepType.phone:
            return TextInputType.phone;
            break;
          case StepType.username:
          case StepType.password:
            return TextInputType.text;
            break;
          default:
            return TextInputType.text;
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return ScopedModel<LoginModel>(
          model: LoginModel(),
          child: Scaffold(
            body: Material(
              child: Container(
                color: Colors.white,
                child: ListView(
                  children: <Widget>[
                    Padding(
                      padding: const EdgeInsets.only(top: 20.0, bottom: 20.0),
                      child: Image(
                          image: AssetImage("assets/images/landing_screen.jpg")),
                    ),
                    Padding(
                      padding:
                          const EdgeInsets.only(top: 50.0, left: 30.0, right: 30.0),
                      child: ScopedModelDescendant<LoginModel>(
                        builder: (context, child, model) => TextFormField(
                              autofocus: true,
                              decoration: InputDecoration(
                                  hintText: model.steps[model.step].hint,
                                  enabledBorder: UnderlineInputBorder(
                                      borderSide: BorderSide(
                                          color: Color(0xFFE4E4E4), width: 2.0))),
                              keyboardType:
                                  getKeyboard(model.steps[model.step].type),
                              textAlign: TextAlign.center,
                              controller: model.steps[model.step].controller,
                              // textInputAction:
                              //     model.steps[model.step].type == StepType.password
                              //         ? TextInputAction.done
                              //         : TextInputAction.next,
                              obscureText:
                                  model.steps[model.step].type == StepType.password,
                              onEditingComplete:
                                  model.step == model.steps.length - 1
                                      ? null
                                      : model.nextStep,
                            ),
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.only(
                          left: 10.0, right: 10.0, top: 100.0),
                      child: Row(
                        children: <Widget>[
                          Expanded(
                              flex: 1,
                              child: Padding(
                                padding:
                                    const EdgeInsets.only(left: 15.0, right: 15.0),
                                child: ScopedModelDescendant<LoginModel>(
                                  builder: (context, child, model) => FlatButton(
                                        onPressed:
                                            model.step == model.steps.length - 1
                                                ? model.startOver
                                                : model.nextStep,
                                        color: Colors.black,
                                        shape: new RoundedRectangleBorder(
                                            borderRadius:
                                                new BorderRadius.circular(30.0)),
                                        child: Padding(
                                            padding: const EdgeInsets.all(14.0),
                                            child:
                                                model.step == model.steps.length - 1
                                                    ? Text(
                                                        'Start Over',
                                                        style: Theme.of(context)
                                                            .textTheme
                                                            .copyWith(
                                                                button: TextStyle(
                                                              color: Colors.white,
                                                            ))
                                                            .button,
                                                      )
                                                    : Icon(
                                                        Icons.arrow_forward,
                                                        color: Colors.white,
                                                        size: 25.0,
                                                      )),
                                      ),
                                ),
                              )),
                        ],
                      ),
                    )
                  ],
                ),
              ),
            ),
          ),
        );
      }
    }
    

    还有你的login_model.dart

    import 'package:flutter/material.dart';
    import 'package:scoped_model/scoped_model.dart';
    
    enum StepType { username, email, phone, password }
    
    class LoginModel extends Model {
      //steps fields options
      int _step = 0;
    
      int get step => _step;
    
      set step(int value) => _step = value;
    
      var steps = <Step>[
        Step(
            type: StepType.username,
            field: "username",
            controller: new TextEditingController(),
            hint: "How can we call you?"),
        Step(
            type: StepType.email,
            field: "email",
            controller: new TextEditingController(),
            hint: "Your Email goes here"),
        Step(
            type: StepType.phone,
            field: "mobile",
            controller: new TextEditingController(),
            hint: "Phone number ex: +201234..."),
        Step(
            type: StepType.password,
            field: "password",
            controller: new TextEditingController(),
            hint: "your Password"),
      ];
    
      void startOver() {
        _step = 0;
        notifyListeners();
      }
    
      void saveStep(String value) {
        nextStep();
      }
    
      void nextStep() {
        _step++;
        notifyListeners();
      }
    
      void previousStep() {
        _step--;
        notifyListeners();
      }
    }
    
    class Step {
      String field;
      TextEditingController controller;
      String hint;
      StepType type;
    
      Step({this.field, this.controller, this.hint, this.type});
    }
    

相关问题