Flutter开发 - 使用GetX框架实现类似MVVM架构
Posted 上马定江山
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter开发 - 使用GetX框架实现类似MVVM架构相关的知识,希望对你有一定的参考价值。
回顾原生开发
在android原生开发中,通常是使用Databinding实现MVVM架构,只需要在gradle中开启databinding的选项,然后使用ObservableField或LiveData即可。
buildFeatures
dataBinding true
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable name="m" type="com.example.vm.LoginViewModel" />
</data>
<EditText android:text="@m.username"/>
</layout>
在ViewModel中可以定义ObservableField,这样界面就可以直接观察了。简单看一下ObservableField的源码,其实还有另外的几个类也是类似的功能,比如ObservableInt和ObservableBoolean。
package androidx.databinding;
import androidx.annotation.Nullable;
import java.io.Serializable;
/**
* An object wrapper to make it observable.
* <p>
* Observable field classes may be used instead of creating an Observable object. It can also
* create a calculated field, depending on other fields:
* <pre><code>public class MyDataObject
* private Context context;
* public final ObservableField<String> first = new ObservableField<String>();
* public final ObservableField<String> last = new ObservableField<String>();
* public final ObservableField<String> display =
* new ObservableField<String>(first, last)
* @Override
* public String get()
* return context.getResources().getString(R.string.name, first.get, last.get());
*
* ;
* public final ObservableInt age = new ObservableInt();
* </code></pre>
* Fields of this type should be declared final because bindings only detect changes in the
* field's value, not of the field itself.
*
* @param <T> The type parameter for the actual object.
* @see ObservableParcelable
*/
public class ObservableField<T> extends BaseObservableField implements Serializable
static final long serialVersionUID = 1L;
private T mValue;
/**
* Wraps the given object and creates an observable object
*
* @param value The value to be wrapped as an observable.
*/
public ObservableField(T value)
mValue = value;
/**
* Creates an empty observable object
*/
public ObservableField()
/**
* Creates an ObservableField that depends on @code dependencies. Typically,
* ObservableFields are passed as dependencies. When any dependency
* notifies changes, this ObservableField also notifies a change.
*
* @param dependencies The Observables that this ObservableField depends on.
*/
public ObservableField(Observable... dependencies)
super(dependencies);
/**
* @return the stored value.
*/
@Nullable
public T get()
return mValue;
/**
* Set the stored value.
*
* @param value The new value
*/
public void set(T value)
if (value != mValue)
mValue = value;
notifyChange();
databinding里面的ObservableField类可以帮助我们很好的实现数据的双向绑定,通过调用它 的get()方法就可以拿到值了,在xml中也可以很方便地使用其值。 这样一种优雅的写法,在Flutter中怎么玩呢?还是那句话,巧妇难为无米之炊,首先你得有Flutter的开发环境,要不然你也就只能看看了。如果不了解Flutter环境怎么搭建的可以看juejin.cn/post/718557… 这篇文章。那么我们开向幼儿园的车马上就要发车了。不好意思,说错了,是开往大前端大佬的车。
框架搭建
我们先大概了解下Flutter项目的项目结构,由于这是一个演示Demo,我这里就不分包了,你们可以写的更优雅。集成get框架就一个命令,flutter就是这么简单。
flutter pub add get
内行人一眼就看出我们肯定是先看main.dart文件。
import 'package:flutter/material.dart';
import 'package:flutter_mvvm_demo/home_binding.dart';
import 'package:flutter_mvvm_demo/main_binding.dart';
import 'package:flutter_mvvm_demo/home_view.dart';
import 'package:flutter_mvvm_demo/main_view.dart';
import 'package:get/get.dart';
void main()
runApp(const MyApp());
class MyApp extends StatelessWidget
const MyApp(super.key);
@override
Widget build(BuildContext context)
return GetMaterialApp(
initialRoute: '/home',
getPages: [
GetPage(
name: '/home',
page: () => const HomeView(),
binding: HomeBinding(),
),
GetPage(
name: '/main',
page: () => const MainView(),
binding: MainBinding(),
),
],
);
这个MyApp就是我们程序的入口,相当于Application类,其实最主要是因为在main()方法中调了一个runApp()方法,然后传入了我们的第一个视图。在Flutter中,不是管View叫视图。Flutter中的视图有两种,一种是有状态的StatefulWidget,还有一种是无状态的StatelessWidget。我们这里返回了一个GetMaterialApp,里面指定了两个属性。initialRoute代表第一个页面的路由,getPages中指定所有的页面。GetPage里面的page指定了这个页面的视图Widget,然后使用binding指定依赖注入,简单说就是不用在使用的时候new对象,直接注入到属性中。
import 'package:flutter_mvvm_demo/home_controller.dart';
import 'package:get/get.dart';
class HomeBinding extends Bindings
@override
void dependencies()
Get.put(HomeController());
import 'package:flutter_mvvm_demo/main_controller.dart';
import 'package:get/get.dart';
class MainBinding extends Bindings
@override
void dependencies()
Get.put(MainController());
调用Get.put()方法我们就注入了controller,之后我们可以直接在视图层拿到这个controller。
import 'package:flutter/material.dart';
import 'package:flutter_mvvm_demo/home_controller.dart';
import 'package:get/get.dart';
class HomeView extends GetView<HomeController>
const HomeView(super.key);
@override
Widget build(BuildContext context)
return Center(
child: ElevatedButton(onPressed: ()
Get.toNamed('/main');
, child: const Text('跳转主界面')) ,
);
import 'package:flutter/material.dart';
import 'package:flutter_mvvm_demo/main_controller.dart';
import 'package:get/get.dart';
class MainView extends GetView<MainController>
const MainView(super.key);
@override
Widget build(BuildContext context)
return Obx(() => Row(children: [
Text('$controller.count'),
ElevatedButton(onPressed: ()
controller.plus();
, child: const Text('+'))
]));
视图层我们直接继承GetView比较方便,这样可以直接拿到之前注入的controller。使用Obx括起来的内容,当被观察的属性值被修改时,直接更新Obx里面的界面。我们再来看一看怎么定义可以被观察的属性,类似于原生开发中ObservableField这样的。
import 'package:get/get.dart';
class MainController extends GetxController
var count = 0.obs;
plus() => count++;
你没有看错,直接在属性值的地方加一个.obs就可以了。这样count的值一旦被修改,就会通知刷新Obs括起来的界面。
作者:dora
链接:https://juejin.cn/post/7200775196113895483
最后
如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。
如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。
全套视频资料:
一、面试合集
二、源码解析合集
三、开源框架合集
欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取↓↓↓
以上是关于Flutter开发 - 使用GetX框架实现类似MVVM架构的主要内容,如果未能解决你的问题,请参考以下文章