Reputation: 77
I hope someone can help me understand ScopedModel in flutter
I have a simple project where when I change a models value, a page wrapper will redirect me to some other page.
In this sample code below, all I want is when I tap login button in the login page, I want the pageWrapper to redirect me to HomePage().
I do notice that after clicking the login button and then I click on the hot reload, I get redirected to the HomePage. which tells me that the model has been updated. Its just that the PageWrapper did not redraw. If thats the case, what should I do so the PageWrapper will redraw when a change has occurred?
Here is a sample code main.dart
void main() => runApp(MyApp(
model: UserInfoModel(),
));
class MyApp extends StatelessWidget {
final UserInfoModel model;
const MyApp({Key key, @required this.model}): super(key: key);
@override
Widget build(BuildContext context) {
return ScopedModel<UserInfoModel>(
model: model,
child: MaterialApp(
title: 'scoped model demo',
home: PageWrapper(),
),
);
}
}
page_wrapper.dart
class PageWrapper extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ScopedModelDescendant<UserInfoModel>(
builder: (context, child, userInfo){
if (userInfo.isLoggedIn){
return Home();
}else{
return Login();
}
}
);
}
}
login.dart
class Login extends StatefulWidget {
@override
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
@override
Widget build(BuildContext context) {
return ScopedModelDescendant<UserInfoModel>(
builder: (context, child, userInfoModel){
return Scaffold(
appBar: AppBar(
title: Text("Login"),
),
body: Container(
child: Center(
child: FlatButton.icon(onPressed: (){
userInfoModel.isLoggedIn=true;
}, icon: Icon(Icons.person,size: 120,),
label: Text("Login"))
),
),
);
});
}
}
home.dart
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Home"),
),
body: Container(
child: Center(
child: Text("you're home"),
),
),
);
}
}
user_info_model.dart
class UserInfoModel extends Model{
String firstName;
String lastName;
bool isLoggedIn=false;
UserInfoModel({
this.firstName,
this.lastName
});
}
Upvotes: 0
Views: 37
Reputation: 54397
You can copy paste run full code below
Step 1: You can interact UserInfoModel
with get
and set
, you can see code below
Step 2: You need notifyListeners()
code snippet
if (userInfo.isLoggedIn) {
return Home();
...
onPressed: () {
userInfoModel.isLoggedIn = true;
},
class UserInfoModel extends Model {
String firstName;
String lastName;
bool _isLoggedIn = false;
UserInfoModel({this.firstName, this.lastName});
bool get isLoggedIn => _isLoggedIn;
set isLoggedIn(bool newSetting) {
_isLoggedIn = newSetting;
notifyListeners();
}
}
working demo
full code
import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
void main() => runApp(MyApp(
model: UserInfoModel(),
));
class MyApp extends StatelessWidget {
final UserInfoModel model;
const MyApp({Key key, @required this.model}) : super(key: key);
@override
Widget build(BuildContext context) {
return ScopedModel<UserInfoModel>(
model: model,
child: MaterialApp(
title: 'scoped model demo',
home: PageWrapper(),
),
);
}
}
class PageWrapper extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ScopedModelDescendant<UserInfoModel>(
builder: (context, child, userInfo) {
if (userInfo.isLoggedIn) {
return Home();
} else {
return Login();
}
});
}
}
class Login extends StatefulWidget {
@override
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
@override
Widget build(BuildContext context) {
return ScopedModelDescendant<UserInfoModel>(
builder: (context, child, userInfoModel) {
return Scaffold(
appBar: AppBar(
title: Text("Login"),
),
body: Container(
child: Center(
child: FlatButton.icon(
onPressed: () {
userInfoModel.isLoggedIn = true;
},
icon: Icon(
Icons.person,
size: 120,
),
label: Text("Login"))),
),
);
});
}
}
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Home"),
),
body: Container(
child: Center(
child: Text("you're home"),
),
),
);
}
}
class UserInfoModel extends Model {
String firstName;
String lastName;
bool _isLoggedIn = false;
UserInfoModel({this.firstName, this.lastName});
bool get isLoggedIn => _isLoggedIn;
set isLoggedIn(bool newSetting) {
_isLoggedIn = newSetting;
notifyListeners();
}
}
Upvotes: 1