The MVVM pattern helps organize your Flutter app by separating the user interface from the business logic. This makes your app easier to build, test, and maintain.
0
0
MVVM pattern in Flutter
Introduction
When you want to keep your UI code simple and focused only on displaying data.
When your app has complex logic that you want to keep separate from the UI.
When you want to write tests for your app's logic without involving the UI.
When working in a team where designers and developers work on UI and logic separately.
When you want to make your app easier to update and add new features.
Syntax
Flutter
class ViewModel { // Holds data and logic } class View extends StatelessWidget { final ViewModel viewModel; View(this.viewModel); @override Widget build(BuildContext context) { // Use viewModel to build UI return Container(); } }
The ViewModel holds the app data and logic.
The View listens to the ViewModel and updates the UI.
Examples
This ViewModel holds a counter and a method to increase it.
Flutter
class CounterViewModel { int count = 0; void increment() { count++; } }
This View shows the current count from the ViewModel.
Flutter
class CounterView extends StatelessWidget { final CounterViewModel viewModel; CounterView(this.viewModel); @override Widget build(BuildContext context) { return Text('Count: ${viewModel.count}'); } }
Sample App
This app uses MVVM to separate the counter logic from the UI. The ViewModel holds the count and notifies the View when it changes. The View listens and updates the displayed count.
Flutter
import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter/material.dart'; class CounterViewModel extends ChangeNotifier { int _count = 0; int get count => _count; void increment() { _count++; notifyListeners(); } } class CounterView extends StatelessWidget { final CounterViewModel viewModel; CounterView({required this.viewModel}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('MVVM Counter')), body: Center( child: AnimatedBuilder( animation: viewModel, builder: (context, _) { return Text('Count: ${viewModel.count}', style: TextStyle(fontSize: 30)); }, ), ), floatingActionButton: FloatingActionButton( onPressed: viewModel.increment, child: Icon(Icons.add), tooltip: 'Increment', ), ); } } void main() { final viewModel = CounterViewModel(); runApp(MaterialApp(home: CounterView(viewModel: viewModel))); }
OutputSuccess
Important Notes
Use ChangeNotifier in ViewModel to notify the View about data changes.
Use AnimatedBuilder or ValueListenableBuilder in the View to rebuild UI on changes.
Keep UI code simple and put all logic in the ViewModel.
Summary
MVVM separates UI (View) from logic (ViewModel) for cleaner code.
ViewModel holds data and notifies View when data changes.
View listens to ViewModel and updates UI automatically.