重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
首先我们知道 GetX 组件里面 obs 状态管理有三种创建属性的方式,我们这里以 List 为例
创新互联公司长期为上千余家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为胶州企业提供专业的网站建设、成都网站建设,胶州网站改版等技术服务。拥有十多年丰富建站经验和众多成功案例,为您定制开发。
视频讲解链接
我们声明了一个类ListController 继承自 GetxController ,用于属性创建以及状态通知的方法,首先我们用三种方式来创建属性并且通过 convertToUpperCase 方法进行对值的改变,然后我们通过调用 update()`方法来进行数据更新,最后我们使用该属性状态的值,接下来我们看一下三种使用方式的对比。
import 'dart:convert';
import 'package:get/get.dart';
class ListController extends GetxController {
// 第一种
final listOne = RxListMap([
{
"name": "Jimi",
"age": 18
}
]);
// 第二种
final listTwo = RxList([
{
"name": "Jimi",
"age": 18
}
]);
// 第三种
final listThree = [{
"name": "Jimi",
"age": 18
}].obs;
void convertToUpperCase() {
listOne.value[0]["name"] = listOne.value.first["name"].toUpperCase();
listTwo.toList().first["name"] = listTwo.toList().first["name"].toString().toUpperCase();
listThree.toList().first["name"] = listTwo.toList().first["name"].toString().toUpperCase();
update();
}
}
我们在页面中获取状态更新的值
import 'package:flutter/material.dart';
import 'package:flutter_getx_dvanced_example/ListController.dart';
import 'package:get/get.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
ListController listController = Get.put(ListController());
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: "GetX",
home: Scaffold(
appBar: AppBar(
title: Text("GetX"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GetBuilderListController(
init: listController,
builder: (controller) {
return Text(
"我的名字是 {controller.listTwo.first['name']}",
style: TextStyle(color: Colors.green, fontSize: 30),
);
},
),
SizedBox(height: 20,),
GetBuilderListController(
init: listController,
builder: (controller) {
return Text(
"我的名字是 ${controller.listThree.first['name']}",
style: TextStyle(color: Colors.green, fontSize: 30),
);
},
),
SizedBox(height: 20,),
ElevatedButton(
onPressed: () {
listController.convertToUpperCase();
},
child: Text("转换为大写"))
],
),
),
),
);
}
}
/pre
|`
效果展示
RxT 继承自 _RxImplT , _RxImplT 又继承 RxNotifierT 并混合 RxObjectMixinT 类
RxImplT 它主要的作用是管理泛型的所有逻辑的。
RxObjectMixinT 它主要的作用是管理注册到 GetX 和 Obx 的全局对象,比如 Widget 的 Rx 值
RxT 它主要的作用是将自定义模型类用Rx`来进行包装,
class RxT extends _RxImplT {
Rx(T initial) : super(initial);
@override
dynamic toJson() {
try {
return (value as dynamic)?.toJson();
} on Exception catch (_) {
throw '$T has not method [toJson]';
}
}
}
abstract class _RxImplT extends RxNotifierT with RxObjectMixinT {
_RxImpl(T initial) {
_value = initial;
}
void addError(Object error, [StackTrace? stackTrace]) {
subject.addError(error, stackTrace);
}
StreamR mapR(R mapper(T? data)) = stream.map(mapper);
void update(void fn(T? val)) {
fn(_value);
subject.add(_value);
}
void trigger(T v) {
var firstRebuild = this.firstRebuild;
value = v;
if (!firstRebuild) {
subject.add(v);
}
}
}
/pre
|`
RxListE 继承自 ListMixinE 实现了 RxInterfaceListE 并混合了 NotifyManagerListE, RxObjectMixinListE
RxListE 它的主要作用是创建一个类似于 ListT 的一个列表
class RxListE extends ListMixinE
with NotifyManagerListE, RxObjectMixinListE
implements RxInterfaceListE {
RxList([ListE initial = const []]) {
_value = List.from(initial);
}
factory RxList.filled(int length, E fill, {bool growable = false}) {
return RxList(List.filled(length, fill, growable: growable));
}
factory RxList.empty({bool growable = false}) {
return RxList(List.empty(growable: growable));
}
/// Creates a list containing all [elements].
factory RxList.from(Iterable elements, {bool growable = true}) {
return RxList(List.from(elements, growable: growable));
}
/// Creates a list from [elements].
factory RxList.of(IterableE elements, {bool growable = true}) {
return RxList(List.of(elements, growable: growable));
}
/// Generates a list of values.
factory RxList.generate(int length, E generator(int index),
{bool growable = true}) {
return RxList(List.generate(length, generator, growable: growable));
}
/// Creates an unmodifiable list containing all [elements].
factory RxList.unmodifiable(Iterable elements) {
return RxList(List.unmodifiable(elements));
}
@override
IteratorE get iterator = value.iterator;
@override
void operator []=(int index, E val) {
_value[index] = val;
refresh();
}
/// Special override to push() element(s) in a reactive way
/// inside the List,
@override
RxListE operator +(IterableE val) {
addAll(val);
refresh();
return this;
}
@override
E operator [](int index) {
return value[index];
}
@override
void add(E item) {
_value.add(item);
refresh();
}
@override
void addAll(IterableE item) {
_value.addAll(item);
refresh();
}
@override
int get length = value.length;
@override
@protected
ListE get value {
RxInterface.proxy?.addListener(subject);
return _value;
}
@override
set length(int newLength) {
_value.length = newLength;
refresh();
}
@override
void insertAll(int index, IterableE iterable) {
_value.insertAll(index, iterable);
refresh();
}
@override
IterableE get reversed = value.reversed;
@override
IterableE where(bool Function(E) test) {
return value.where(test);
}
@override
IterableT whereTypeT() {
return value.whereTypeT();
}
@override
void sort([int compare(E a, E b)?]) {
_value.sort(compare);
refresh();
}
}
/pre
|`
当我们在调用 .obs 的时候其实内部的实现源码还是通过 RxListe(this) 进行了一层包装,设计这个主要的目的就是为了方便开发者进行使用
ListExtensionE on ListE {
RxListE get obs = RxListE(this);
/// Add [item] to [ListE] only if [item] is not null.
void addNonNull(E item) {
if (item != null) add(item);
}
// /// Add [IterableE] to [ListE] only if [IterableE] is not null.
// void addAllNonNull(IterableE item) {
// if (item != null) addAll(item);
// }
/// Add [item] to ListE only if [condition] is true.
void addIf(dynamic condition, E item) {
if (condition is Condition) condition = condition();
if (condition is bool condition) add(item);
}
/// Adds [IterableE] to [ListE] only if [condition] is true.
void addAllIf(dynamic condition, IterableE items) {
if (condition is Condition) condition = condition();
if (condition is bool condition) addAll(items);
}
/// Replaces all existing items of this list with [item]
void assign(E item) {
// if (this is RxList) {
// (this as RxList)._value;
// }
}
/// Replaces all existing items of this list with [items]
void assignAll(IterableE items) {
// if (this is RxList) {
// (this as RxList)._value;
// }
clear();
addAll(items);
}
}
/pre
|`
我们对 RxT([]) 、 RxListE 、 .obs 进行了一个总结,在我们平时的开发过程中建议大家使用 .obs 即可,因为这是最简单的方式。
新手最近在使用Getx做状态管理, 在使用中遇到问题, 随手记录下,
提示错误:
GET the improper use of a getx has been detected you should only use getx or obx for the specific widget that will be updated. if you are seeing this error, you probabaly did not insert any observable variables into GetX/Obx...
其实提示很明显, 就是Obx()中组件没用到controller内容, 比如Obx(()=Text("123")), 这里面Obx没有用到GetxController的对象, 就会报这个错误,如果改成Obx(()=Text(controller.content)), 就可以了
一、前言
Flutter开发,就需要对各种状态的管理,就是在请求数据的时候需要实时变化,各种交互变化等,在没有使用GetX之前使用Provider,用Provider的时候觉得真香,挺方便的,需要刷新的时候直接 notifyListeners(); 用了GetX之后觉得Provider太繁琐了。这边介绍下GetX的使用以及常用的方法。
二、 GetX
GetX 是 Flutter 上的一个轻量且强大的解决方案:高性能的状态管理、智能的依赖注入和便捷的路由管理。
1、相关优势:
三、使用
1、第一步 引入get
2、第二步
修改入口、配置路由
3、路由
Routes类
Pages类
4、状态管理
我一般一个page对应一个controller, controller来处理逻辑,控制page.
简单使用
5、依赖注入
依赖注入也是我喜欢的,可以减少很多工作。
第一步
第二步
6、跨页面交互
7、黑暗模式
可以参考前期写的博客。 黑暗模式的适配
GetX 是 Flutter 上的一个轻量且强大的解决方案:高性能的状态管理、智能的依赖注入和便捷的路由管理。
GetX的优势
对比provider,GetX可能更受欢迎
下面是GetX在pub上面的likes数据
下面是GetX在github上面的star数据
GetX 因为不需要上下文,突破了InheritedWidget的限制,我们可以在全局和模块间共享状态,这正是 BLoc 、Provider 等框架的短板
1、 在MaterialApp前添加 "Get",将其变成GetMaterialApp。
2、创建业务逻辑类,并将所有的变量,方法和控制器放在里面。 你可以使用一个简单的".obs "使任何变量成为可观察的。
3、引用逻辑类,在界面显示
几个注意点
1、
与
效果一样
2、
与
效果一样
3、
与
效果一样
1、Obx
2、GetX
3、GetBuilder
4、ValueBuilder
;target=VSCodecategory=Programming%20LanguagessortBy=Relevance