laitimes

What makes sense of Flutter's architecture?

author:Senior Internet Architect

Preface

When I first started programming in Flutter, I was almost scared away by Flutter's nested hell, but when I saw that Flutter supports Windows stability, I decided to try to accept Flutter because Flutter really has so much to offer: cross-platform, static compilation, and a hot-loading interface.

Flutter code is written to folders, and the code is managed through folders, like in C++ language, a file, which can be written as a class or as a method.

Unlike Java, where everything is class, uniform, and managed by package name, there is support for similar "guided packages".

So how can you have a framework to optimize your code and make your project look cleaner and easier to maintain, like Java does?

My current answer is MVC, the best architecture is the right architecture, with this architecture, I feel that I have found a home, people look at my code first, and then make a review.

Use sections

Combined with GetX, it can be used as follows:

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:wenznote/commons/mvc/controller.dart';
import 'package:wenznote/commons/mvc/view.dart';

class CustomController extends MvcController {
  var count = 0.obs;

  void addCount() {
    count.value++;
  }
}

class CustomView extends MvcView<CustomController> {
  const CustomView({super.key, required super.controller});

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        children: [
          Obx(() => Text("点击次数:${controller.count.value}")),
          TextButton(
            onPressed: () {
              controller.addCount();
            },
            child: Text("点我"),
          ),
        ],
      ),
    );
  }
}
           

Simply and crudely, design the UI directly in the CustomView, and write the business logic code in the CustomController, such as logging in and registering.

As for where the models in MVC go? Guess what.

Code encapsulation section

The code encapsulation is also very concise, and the encapsulated controller code is as follows

import 'package:flutter/material.dart';

class MvcController with ChangeNotifier {
  late BuildContext context;

  @mustCallSuper
  void onInitState(BuildContext context) {
    this.context = context;
  }

  @mustCallSuper
  void onDidUpdateWidget(BuildContext context, MvcController oldController) {
    this.context = context;
  }

  void onDispose() {}
}
           

The encapsulated view code is as follows

import 'package:flutter/material.dart';
import 'controller.dart';

typedef MvcBuilder<T> = Widget Function(T controller);

class MvcView<T extends MvcController> extends StatefulWidget {
  final T controller;
  final MvcBuilder<T>? builder;

  const MvcView({
    super.key,
    required this.controller,
    this.builder,
  });

  Widget build(BuildContext context) {
    return builder?.call(controller) ?? Container();
  }

  @override
  State<MvcView> createState() => _MvcViewState();
}

class _MvcViewState extends State<MvcView> with AutomaticKeepAliveClientMixin{
  @override
  bool get wantKeepAlive => true;

  @override
  void initState() {
    super.initState();
    widget.controller.onInitState(context);
    widget.controller.addListener(onChanged);
  }

  void onChanged() {
    if (context.mounted) {
      setState(() {});
    }
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    widget.controller.context = context;
    return widget.build(context);
  }

  @override
  void didUpdateWidget(covariant MvcView<MvcController> oldWidget) {
    super.didUpdateWidget(oldWidget);
    widget.controller.onDidUpdateWidget(context, oldWidget.controller);
  }


  @override
  void dispose() {
    widget.controller.removeListener(onChanged);
    widget.controller.onDispose();
    super.dispose();
  }
}
           

epilogue

MVC can easily and quickly isolate the business code from the UI code, just go to the Controller when you change the logic, just go to the View when you change the UI, and the same idea as the back-end development, just complete the work.

Attached is a screenshot of the file structure of the work, pro-spray ha~

What makes sense of Flutter's architecture?

Thank you for your attention and support, and continue to update more flutter cross-platform development knowledge in the future, such as: Where should the Controller be created in the MVC architecture? Where should the Service in the Controller be created?

Author: Jelly Orange Orange Jun

Link: https://juejin.cn/post/7340472228927914024