I am new to flutter and I wanted to manage a login screen page that has one text field and when the user click next I save the value and change the hint text to the next step hint on the same text field using scoped model state management.
first here is my code:
loginBase.dart(the main login page class that has both "login field (imported)" and "login button"):
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 (the one containing the field):
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,
),
);
}
and finally the login-model.dart (that contain the scoped model for the login page):
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});
}
The issue is:
when I call the nextStep()
function the hint text value change in the model but not updated in the login page, Am I applying it in a wrong way?