Flutter plugin to rapidly create a Page with MVVM design pattern

Overview

mvvm_builder

mvvm_builder is a Flutter plugin to help you implement MVVM design pattern with flutter. MVVM = Model - View - ViewModel

Installation

To use this plugin, add mvvm_builder as a dependency in your pubspec.yaml file.

Why use MVVM design patterns

Widely used in Android and iOS native development. This pattern is one of the best to handle complex page with testable code. Implement a good design pattern can just simplify code, make more code testable, allow better performance... The idea is to split business logic from your view. Your view has to stay dumb, and this plugin will help you to respect the pattern.

Usage

1 - import MVVMPage Widget from package

import 'package:mvvm_builder/mvvm_builder.dart';

2 - Create your Model

class MyViewModel extends MVVMModel {
  String title;
  List<TodoModel> todoList;
}

class TodoModel {
  String title, subtitle;

  TodoModel(this.title, this.subtitle);
}

3 - Create your Presenter

class MyPresenter extends Presenter<MyViewModel, MyViewInterface> {

  MyPresenter(MyViewModel model, MyViewInterface view) : super(model, view);

  @override
  Future onInit() async {
    // do initialisation stuff on your viewmodel here, loading... etc
    this.viewModel.title = "My todo list";
    this.viewModel.todoList = List();
    // init your view model here -- load from network etc ... 
    for(int i = 0; i < 15; i++) {
      this.viewModel.todoList.add(new TodoModel("TODO $i", "my task $i"));
    }
    this.refreshView(); // call this at the end if onInit takes time
  }
}

4 - define your view interface

for example:

abstract class MyViewInterface {
  
  void showMessage(String message);
  
}

5 - Create your Page

Use directly MVVMPage

You page must implement your view interface. For example :

class _MyAppState extends State<MyApp> implements MyViewInterface{
  
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();

  @override
  void initState() {
    super.initState();
  }


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MVVMPage<MyPresenter, MyViewModel>(
        builder: (context, presenter, model) {
          return Scaffold(
            // ...
          );
        },
        presenter: MyPresenter(new MyViewModel(), this),
      )
    );
  }

  @override
  void showMessage(String message) {
    _scaffoldKey.currentState.showSnackBar(new SnackBar(content: Text(message)));
  }
}

Use a Mvvmbuilder

Using a builder defer build and presenter creation until you actually need it. This can be also usefull if you want to keep a page state in your memory. Prefer use this method to use this page within a route. MVVMPageBuilder stores a version of your page in cache after first time it's build. Ex:

class MyAppWithBuilder extends StatelessWidget implements MyViewInterface {

  //...
  final mvvmPageBuilder = MVVMPageBuilder<MyPresenter, MyViewModel>();

  @override
  Widget build(BuildContext context) {
    return mvvmPageBuilder.build(
      context: context,
      presenterBuilder: (context) => MyPresenter(new MyViewModel(), this),
      builder: (context, presenter, model) {
        return Scaffold(
            /** ... */
        );
      },
    );
  }

  @override
  void showMessage(String message) {
    _scaffoldKey.currentState.showSnackBar(new SnackBar(content: Text(message)));
  }
}

Application routes

As said in previous section, builder can be usefull to keep a page state across rebuilds. This only store the way you create a page. Prefer this method as it's easyer and much better. Ex:

final homePageBuilder = MyAppWithBuilder();

Route<dynamic> route(RouteSettings settings) {
  print("...[call route] ${settings.name}");
  switch (settings.name) {
    case "/":
      return MaterialPageRoute(builder: homePageBuilder.build);
  }
}


void main() {
  print("...[main]");
  return runApp(
   MaterialApp(
     onGenerateRoute: route,
   )
  );
}

Test

This pattern is really usefull for testing as it allows you to test business logic separately from rendering. The another good thing of this pattern is the ability to test your view with many combination of viewModel settings without the need of chaining actions before having the desired view state. You can now test your view alone, presenter alone and test them together.

Use animations

MVVMPage can help you construct a simple Page with animations. Just provide a way to create an AnimationController and use the animation listener to handle animations.

class MyApp extends StatelessWidget implements MyViewInterface {

  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
  
  // prefer to create your presenter outside of build method to keep it's state safe
  final MyPresenter mPresenter = MyPresenter.create(null);

  MyApp() {
    // must be called to be able to use [MyViewInterface] in our presenter
    mPresenter.init(this);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MVVMPage<MyPresenter, MyViewModel>(
        builder: (context, presenter, model) {
          var animation = new CurvedAnimation(
            parent: context.animationController,
            curve: Curves.easeIn,
          );
          return Scaffold(
            key: _scaffoldKey,
            appBar: AppBar(title: Text(model.title)),
            body: ListView.separated(
              itemBuilder: (context, index) => InkWell(
                onTap: () => presenter.onClickItem(index),
                child: AnimatedBuilder(
                  animation: animation,
                  builder: (context, child) => Opacity(opacity: animation.value, child: child),
                  child: ListTile(
                    title: Text(model.todoList[index].title),
                    subtitle: Text(model.todoList[index].subtitle),
                  ),
                ),
              ),
              separatorBuilder: (context, index) => Divider(height: 1) ,
              itemCount: model.todoList.length
            )
          );
        },
        presenter: mPresenter, 
        singleAnimControllerBuilder: (tickerProvider) => AnimationController(vsync: tickerProvider, duration: Duration(seconds: 1)),
        animListener: (context, presenter, model) {
          if(model.fadeInAnimation) {
            context.animationController
              .forward()
              .then((value) => presenter.onFadeInAnimationEnd());
          }
        },
      )
    );
  }

  @override
  void showMessage(String message) {
    _scaffoldKey.currentState.showSnackBar(new SnackBar(content: Text(message)));
  }

}

singleAnimControllerBuilder : creates your animations controller. animListener : handle the state of your animations.

To fire animListener simply call refreshAnimations from your presenter. Now you can handle animations state directly from your presenter.

Final note

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

You might also like...

Login-page-ui - An animated login page, designed with dart

Login-page-ui - An animated login page, designed with dart

Beautiful Login Page UI Design and Animation ScreenShots This is one of my best

Nov 22, 2022

Login-with-Register-page - A Login with Register page combined with all movable images made with Dart

Login-with-Register-page - A Login with Register page combined with all movable images made with Dart

Flutter login page with register page A new dart project designed for login page

Aug 2, 2022

Another way to build Flutter applications for mobile, web and desktop using the powerful of MVC Design Pattern.

Another way to build Flutter applications for mobile, web and desktop using the powerful of MVC Design Pattern.

Karee Another way to build Flutter applications for mobile, web and desktop using the powerful of MVC Design Pattern. + = About Karee Karee is a frame

Sep 29, 2022

đź‘‘ The lightweight design pattern for small management applications.

đź‘‘ The lightweight design pattern for small management applications.

Store Pattern đź‘‘ The lightweight design pattern for small management applications. Features | Structure | Install | Usage | Documents | Technologies |

Sep 26, 2022

Flutter Architecture Blueprints is a project that introduces MVVM architecture and project structure approaches to developing Flutter apps.

Flutter Architecture Blueprints is a project that introduces MVVM architecture and project structure approaches to developing Flutter apps.

Flutter Architecture Blueprints Flutter Architecture Blueprints is a project that introduces MVVM architecture and project structure approaches to dev

Apr 9, 2022

Flutter Architecture Blueprints is a project that introduces MVVM architecture and project structure approaches to developing Flutter apps.

Flutter Architecture Blueprints is a project that introduces MVVM architecture and project structure approaches to developing Flutter apps.

Flutter Architecture Blueprints Flutter Architecture Blueprints is a project that introduces MVVM architecture and project structure approaches to dev

Dec 31, 2022

Boilerplate for Flutter + GetX MVVM

flutter_getx_boilerplate A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you

May 31, 2022

A basic boilerplate template for starting a Flutter GetX project. GetX, Dio, MVVM, get CLI, Localization, Pagination etc are implemented.

A basic boilerplate template for starting a Flutter GetX project. GetX, Dio, MVVM, get CLI, Localization, Pagination etc are implemented.

Flutter GetX Template (GetX, Dio, MVVM) This Flutter Template using GetX package for State management, routing and Dependency Injection (bindings). We

Jan 9, 2023

A Flutter MVVM provider demo application.

A Flutter MVVM provider demo application.

Flutter MVVM + Provider Demo A Flutter MVVM provider demo application. Demo About It simply loads Posts data from API and render the posts on the scre

Oct 17, 2022
Comments
  • where init presenter?

    where init presenter?

    @override
      void initState() {
        super.initState();
      }
    
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: MVVMPage<MyPresenter, MyViewModel>(
            builder: (context, presenter, model) {
              return Scaffold(
                // ...
              );
            },
            presenter: MyPresenter(new MyViewModel(), this),
          )
        );
      }
    

    if init presenter in build method, May cause present create many times, Whether to consider putting it elsewhere,such as 'initState()'?

    opened by jasonlee3652 5
  • Why not use ChangeNotifierProvider?

    Why not use ChangeNotifierProvider?

    replace PresenterInherited to ChangeNotifierProvider let MVVMModel extends ChangeNotifier, so not need forceRefreshView method, use MVVMModel.notifyListeners(). What do you think?

    I like your way of thinking, it can divide the logic very well, but I don’t understand whether this is mvvm or mvc.

    opened by jasonlee3652 3
  • Was bored, so did a

    Was bored, so did a "code review"

    Put it at https://github.com/miyoyo/flutter_mvvm. Feel free to take whatever you want from it, or ignore it 🤷‍♀️

    Also, just a passing thought, but are you sure this is MVVM and not some kind of MVP-MVVM hybrid? Not exactly sure what a presenter is doing here, but then again I'm no expert on the pattern.

    opened by miyoyo 1
Releases(2.1.5)
Owner
Gautier
Gautier
Flutter mvvm archi - Flutter Advanced Course - Clean Architecture With MVVM

flutter_mvvm_archi A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you start

Namesh Kushantha 0 Jan 8, 2022
I created a welcome page, login page and signup page using Flutter

welcome_page UI design for welcome page, signUp page & Login page by Joy Obor Getting Started This project is a starting point for a Flutter applicati

spyder 0 Dec 29, 2021
Flutter app using MVVM architecture pattern , dio , provider , intl packages.

News App Simple news application using free news API for fetching realtime data from the internet. Features -Used MVVM architecture pattern. Packages

null 3 Mar 25, 2022
Screener: a sample application Uses MVVM pattern

screener This is a sample application. Uses MVVM pattern Tries to encourage the use of boundaries (by using the concept of packages) Getting Started ?

Behruz Hurramov 0 Dec 27, 2021
Glass-Design - Glass Design on one page writing in Flutter

glassdesign writing in Flutter framework / GlassDesign fait en Flutter framework

Tommy 6 Jun 15, 2022
NesPad-design-in-flutter - Create a design in flutter for a NesPad

NesPad Design in Flutter Diseño de un NesPad usando flutter nativo. Se hizo util

null 0 Jan 3, 2022
Smooth-Page-Indicator-Example-Flutter - A simple example about smooth page indicator in Flutter

Smooth Page Indicator Example - Flutter Screenshots ⚠️ Essential Packages smooth

AmirHossein Bayat 6 Dec 7, 2022
A package that offers various page indicators inlcuding a Flutter implementation of the Ink Page Indicator

A package that offers various page indicators inlcuding a Flutter implementation of the Ink Page Indicator. See below for more examples.

null 50 Jan 6, 2022
OnBoarding Animation provides page like animation to the onBoarding screens with the page indicator

OnBoarding Animation OnBoarding Animation provides page like animation to the onBoarding screens with the page indicator. Screenshots and Screen recor

null 13 Oct 12, 2022