Logo

dev-resources.site

for different kinds of informations.

Design Pattern in Flutter MVVM

Published at
1/8/2025
Categories
dart
flutter
mobile
programming
Author
sukmarizki04
Categories
4 categories in total
dart
open
flutter
open
mobile
open
programming
open
Author
12 person written this
sukmarizki04
open
Design Pattern in Flutter MVVM

Purpose: The MVVM (Model-View-ViewModel) pattern is used to separate the UI (View) from the business logic and data (Model) in Flutter applications. This separation improves code maintainability, testability, and scalability.
Core Concepts:

Model: Represents the data and business logic.
View: Displays the data and listens to user interactions.
ViewModel: Acts as a mediator between the View and the Model. It handles the presentation logic and exposes data to the View.
Benefits:
Separation of Concerns: Keeps the UI code separate from the business logic.
Testability: Makes it easier to test the business logic and UI separately.
Maintainability: Simplifies the codebase and makes it easier to maintain.
Example Code:
Let’s create a simple counter app using the MVVM pattern.

Step 1: Create the Model


// models/counter_model.dart
class CounterModel {
  int counter;

  CounterModel({this.counter = 0});
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Create the ViewModel

// viewmodels/counter_view_model.dart
import 'package:flutter/material.dart';
import '../models/counter_model.dart';

class CounterViewModel extends ChangeNotifier {
  CounterModel _counterModel = CounterModel();

  int get counter => _counterModel.counter;

  void increment() {
    _counterModel.counter++;
    notifyListeners();
  }

  void decrement() {
    _counterModel.counter--;
    notifyListeners();
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Provide the ViewModel
Wrap your main app widget with a ChangeNotifierProvider:

// main.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'viewmodels/counter_view_model.dart';
import 'views/counter_page.dart';

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => CounterViewModel(),
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CounterPage(),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Create the View
Use the Consumer widget to listen to changes and rebuild the UI:

// views/counter_page.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../viewmodels/counter_view_model.dart';

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('MVVM Counter'),
      ),
      body: Center(
        child: Consumer<CounterViewModel>(
          builder: (context, counterViewModel, child) {
            return Text(
              'Counter: ${counterViewModel.counter}',
              style: TextStyle(fontSize: 24),
            );
          },
        ),
      ),
      floatingActionButton: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          FloatingActionButton(
            onPressed: () => context.read<CounterViewModel>().increment(),
            child: Icon(Icons.add),
          ),
          SizedBox(height: 8),
          FloatingActionButton(
            onPressed: () => context.read<CounterViewModel>().decrement(),
            child: Icon(Icons.remove),
          ),
        ],
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

In this example, the CounterModel class holds the data. The CounterViewModel class acts as a mediator between the model and the UI, handling the presentation logic. The CounterPage widget is the View, which uses the CounterViewModel to display and interact with the counter data.

By using the MVVM pattern, we achieve a clean separation of concerns, making our code more maintainable and testable.

dart Article's
30 articles in total
Favicon
Flutter vs React Native in 2025: A Comprehensive Comparison
Favicon
Deploying Flutter Web Apps using Globe.dev
Favicon
Journey to Clean Architecture: Wrestling with a 10k Line Flutter Legacy Codebase
Favicon
5 Essential Flutter Widgets Every Developer Should Master
Favicon
Mastering Nested Navigation in Flutter with `go_router` and a Bottom Nav Bar
Favicon
Flutter for Beginners: From Installation to Your First App
Favicon
Building a Beautiful Login Screen in Flutter: A Complete Guide
Favicon
Flutter Design Pattern Bussines Logic Component (BLOC)
Favicon
Create Different Type of Flavor on Flutter Application
Favicon
Handling PathAccessException in iOS for File Download
Favicon
Common mistakes in Flutter article series
Favicon
Design Pattern in Flutter MVVM
Favicon
7 Ways to Refactor Your Flutter Application
Favicon
WebRTC vs Agora Video SDK vs ZegoCloud for Video Calling in Flutter: A Comprehensive Comparison
Favicon
From Chaos to Control: The Day I Learned the Magic of Debouncing in Flutter πŸš€
Favicon
Syntax of comments in dart
Favicon
My first Dart program
Favicon
Integrate the Gemini REST API in Flutter: Unlock Powerful Generative Language Models for Your Next App
Favicon
Dart Operators Explained in Bangla
Favicon
Control Flow Statements (switch and case) in Dart (Bangla)
Favicon
break, continue in Dart programming (Bangla)
Favicon
Control Flow Statements ( for, while, do-while ) in dart (Bangla)
Favicon
Control Flow Statements ( if, else, else if) in dart (Bangla)
Favicon
Type inference in Dart programming (Bangla)
Favicon
var, final, const in dart programming
Favicon
We are in Top 5 Flutter Of The Year Apps List
Favicon
Class in dart
Favicon
Function in dart
Favicon
Map in Dart
Favicon
List in Dart

Featured ones: