I use a MVVM Approach like it is described here https://www.filledstacks.com/post/flutter-architecture-my-provider-implementation-guide/
with the Stacked package
https://pub.dev/packages/stacked
All data is stored in repositories and also most of the logic will be done here. View Models just call the required functions from services or repositories.
If a new service is added it needs to be added to get_it in the locator.dart
setupLocator() {
getIt.registerSingleton(AuthService());
getIt.registerSingleton(Api());
getIt.registerSingleton(SharedPreferencesHelper());
}
//Calling a service in e.g. a viewModel
getIt<AuthService>().logout();
The folder /views holds Screens and View Models
/screens
// View
class HomeView extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Using the reactive constructor gives you the traditional viewmodel
// binding which will excute the builder again when notifyListeners is called.
return ViewModelBuilder<HomeViewModel>.reactive(
viewModelBuilder: () => HomeViewModel(),
onModelReady: (model) => model.initialise(),
builder: (context, model, child) => Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
model.updateTitle();
},
),
body: Center(
child: Text(model.title),
),
),
);
}
}
/viewmodels
abstract class BaseViewModel extends ChangeNotifier {
bool isLoading = false;
void setLoading(bool loading) {
isLoading = loading;
notifyListeners();
}
}
class HomeViewModel extends BaseViewModel {}
/widgets
Routing is done with the help of Get → https://pub.dev/packages/get