Skip to content

Instantly share code, notes, and snippets.

@Tulakshana
Last active June 12, 2025 23:10
Show Gist options
  • Save Tulakshana/a02b19263e82a0fb799d30a5d712367b to your computer and use it in GitHub Desktop.
Save Tulakshana/a02b19263e82a0fb799d30a5d712367b to your computer and use it in GitHub Desktop.
MVVM is an acronym for Model-View-ViewModel. The ViewModel handles logic and state, while View is only for UI, and Model handles data. This is how we could implement this in Flutter. Further reading: https://docs.flutter.dev/app-architecture/guide.
/*
Purpose: Represents your data layer (e.g. API responses, local database models).
*/
class User {
final String name;
final int age;
User({required this.name, required this.age});
}
/*
Purpose: Handles the UI. It displays data and listens to changes from the ViewModel.
Contains: Stateless or Stateful Widgets, observing ViewModel.
*/
class UserView extends StatelessWidget {
@override
Widget build(BuildContext context) {
final viewModel = context.watch<UserViewModel>();
return Scaffold(
appBar: AppBar(title: Text("User")),
body: Center(
child: viewModel.isLoading
? CircularProgressIndicator()
: Text('Name: ${viewModel.user?.name ?? "No user"}'),
),
floatingActionButton: FloatingActionButton(
onPressed: () => viewModel.loadUser(),
child: Icon(Icons.refresh),
),
);
}
}
/*
Purpose: Holds the business logic and state. It notifies the view when updates happen.
Contains: State variables, logic methods, and ChangeNotifier for state management.
*/
class UserViewModel extends ChangeNotifier {
User? _user;
bool _isLoading = false;
User? get user => _user;
bool get isLoading => _isLoading;
Future<void> loadUser() async {
_isLoading = true;
notifyListeners();
await Future.delayed(Duration(seconds: 2)); // Simulate network delay
_user = User(name: 'Alice', age: 25);
_isLoading = false;
notifyListeners();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment