flutter-tutorials
flutter-tutorials copied to clipboard
Shared model
Hi, I have a question, I have this code:
StartUpScreen:
class StartUpScreen extends StatelessWidget {
const StartUpScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
var userProvider = context.read<UserProvider>();
return ViewModelBuilder<StartUpViewModel>.reactive(
viewModelBuilder: () => StartUpViewModel(),
onModelReady: (model) => model.handleStartUpLogic(),
builder: (context, model, child) => Scaffold(
backgroundColor: Colors.white,
body: model.isBusy
? const CircularProgressIndicator()
: model.isLogged
? const HomeScreen()
: LoginScreen()),
);
}
}
and relative view model:
class StartUpViewModel extends BaseViewModel {
final AuthenticationService _authenticationService = locator<AuthenticationService>();
bool _isLogged = false;
bool get isLogged {
return _isLogged;
}
Future handleStartUpLogic() async {
setBusy(true);
bool hasLoggedInUser = _authenticationService.isUserLoggedIn();
if (hasLoggedInUser) {
_isLogged = true;
setBusy(false);
} else {
_isLogged = false;
setBusy(false);
}
}
}
on lunch application I'm not logged and the app show me LoginScreen:
class LoginScreen extends StatelessWidget {
LoginScreen({Key? key}) : super(key: key);
final emailController = TextEditingController();
final passwordController = TextEditingController();
@override
Widget build(BuildContext context) {
return ViewModelBuilder<LoginViewModel>.reactive(
viewModelBuilder: () => LoginViewModel(),
builder: (context, model, child) => Scaffold(
backgroundColor: Colors.white,
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 50),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 150,
child: Image.asset('assets/images/title.png'),
),
InputField(
placeholder: 'Email',
controller: emailController,
),
verticalSpaceSmall,
InputField(
placeholder: 'Password',
password: true,
controller: passwordController,
),
verticalSpaceMedium,
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
BusyButton(
title: 'Login',
busy: model.isBusy,
onPressed: () {
model.login(
email: emailController.text,
password: passwordController.text,
);
},
)
],
),
verticalSpaceMedium,
],
),
),
),
);
}
}
and relative view model:
class LoginViewModel extends BaseViewModel {
final AuthenticationService _authenticationService = locator<AuthenticationService>();
final DialogService _dialogService = locator<DialogService>();
Future<void> login({
required String email,
required String password,
}) async {
try {
setBusy(true);
await _authenticationService.loginWithEmail(
email: "myemail",
password: "mypass!",
);
setBusy(false);
} catch (e) {
setBusy(false);
await _dialogService.showDialog(
title: 'Login Failure',
description: 'General login failure. Please try again later',
);
}
}
}
The question is, how to change model.isLogged on StartUpViewModel for reload the widget and show the LoginScreen simil to classic provider? I could use navigation but this operation can be useful for other pages as well. for example, in classic provider i've a Page A with total coins, in Page B i add 10 coin, with provider i can update the value with notifyListeners(); without call the server. How to emulate this? it's possible?