具有多个类别的Flutter作用域模型

时间:2018-09-10 06:25:49

标签: flutter scoped-model

我是不熟悉flutter的人,我想管理一个具有一个文本字段的登录屏幕页面,当用户单击“下一步”时,我保存了值并将提示文本更改为使用范围模型在同一文本字段上的下一步提示状态管理。

首先这是我的代码:

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 个答案:

答案 0 :(得分: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});
}
相关问题