Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVVM Design Pattern in Flutter

we try to develop a flutter app and we create a stateful widget as a page .
we want to separate build function from other state variable and state function in 2 different file that build function can access to this of state class we creating a class :

PageClassState extend State<PageClass>{
    string value = 'string value';
}

and extend it in a new class that can access PageClassState this variable we write :

PageClassView extend PageClassState{
    @override
    Widget Build(){
      return(new Text(this.value))
    }
} 

but in PageClassState we get an error say we must override build method in the class . is there any suggestion to fix the problem and implement MVVM Design pattern in flutter?

like image 305
javad bat Avatar asked Apr 11 '18 16:04

javad bat


People also ask

Can we use MVVM pattern in Flutter?

The Ultimate Hands-On Flutter & MVVM - Build Real Projects Since design patterns are platform-agnostic, it can be used with any framework, including Flutter.

What is the difference between MVC and MVVM in Flutter?

KEY DIFFERENCEIn MVC, controller is the entry point to the Application, while in MVVM, the view is the entry point to the Application. MVC Model component can be tested separately from the user, while MVVM is easy for separate unit testing, and code is event-driven.

Why MVVM is better than MVC?

MVVM is better than MVC/MVP because of its unidirectional data and dependency flow. Dependency is one way, thus it is a lot easier to decouple it when we need to. It is also easier for testing. All my projects(written in Kotlin for Android app) are based on MVVM.

Which architecture pattern is best for Flutter?

Because the BloC pattern is the most popular architecture for Flutter apps, most developers will always choose it for their Flutter projects, because Flutter is widget-based, and the BloC architecture allows your widgets to communicate with other layers of the application.


2 Answers

I suggest moving your ViewModel code into a separate class that does not extend State. Keep the ViewModel platform independent. Your Widgets state can have an instance of the viewModel and interact with it.

You can find a more detailed example here

If child Widgets need to access your ViewModel you can use a Inherited Widget as suggested by @Rémi Rousselet. I quickly implemented this for you:

class ViewModelProvider extends InheritedWidget {
  final ViewModel viewModel;

  ViewModelProvider({Key key, @required this.viewModel, Widget child}) 
  : super(key: key, child: child);

  @override
  bool updateShouldNotify(InheritedWidget oldWidget) => true;

  static ViewModel of(BuildContext context) =>
      (context.inheritFromWidgetOfExactType(ViewModelProvider) as 
  ViewModelProvider).viewModel;
}

Child widgets can grab the ViewModel by calling

var viewModel = ViewModelProvider.of(context);

Let me know if you have any questions :)

like image 129
JulianLenz Avatar answered Oct 15 '22 08:10

JulianLenz


That's not the proper approach. You shouldn't split State<T> and it's build method. The thing is, don't extend widgets. Compose them.

A correct way to achieve something similar is to use InheritedWidget. These will hold you data but do nothing else. And it's children will be able to request those datas using a MyInherited.of(context).

You could also create a builder. Something like :

typedef Widget MyStateBuilder(BuildContext context, MyStateState state);

class MyState extends StatefulWidget {
  final MyStateState builder;

  const MyState({this.builder}) : assert(builder != null);

  @override
  MyStateState createState() => new MyStateState();
}

class MyStateState extends State<MyState> {
  String name;

  @override
  Widget build(BuildContext context) {
    return widget.builder(context, this);
  }
}
like image 36
Rémi Rousselet Avatar answered Oct 15 '22 08:10

Rémi Rousselet