GetX学习03 局部状态组件

1,432 阅读1分钟

这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战

今天到了第三天, 我们来看看具备状态组件,

flutter版本:2.2.0 dart版本:2.13.0 GetX版本:4.3.4

今天学习的这个组件在最新的flutter版本中由于空安全是使用不了的,报以下错误

type '(bool, (bool) => void) => Switch' is not a subtype of type '(bool?, (bool?) => void) => Widget'

是由于在package:get/get_state_manager/src/simple/simple_builder.dart中的第44行声明了T? value;53行调用了构造者:Widget build(BuildContext context) => widget.builder(value, updater); 因此发生了这个错误

1. 局部状态组件

  1. ValueBuilder的使用方法
ValueBuilder<bool>(
  initialValue: false,
  builder: (value, updateFn) => Switch(
    value: value,
    onChanged: updateFn, // 你可以用( newValue )=> updateFn( newValue )。
  ),
  // 如果你需要调用 builder 方法之外的东西。
  onUpdate: (value) => print("Value updated: $value"),
  onDispose: () => print("Widget unmounted"),
),
  1. ValueBuilder的实现 主要是创建了一个StatefulWidget,通过内部调用setState进行值变更
class _ValueBuilderState<T> extends State<ValueBuilder<T?>> {
  T value;

  @override
  void initState() {
    super.initState();
    value = widget.initialValue;
  }

  @override
  Widget build(BuildContext context) => widget.builder(value, updater);

  void updater(T newValue) {
    if (widget.onUpdate != null) {
      widget.onUpdate!(newValue);
    }
    setState(() {
      value = newValue;
    });
  }

  @override
  void dispose() {
    super.dispose();
    widget.onDispose?.call();
    if (value is ChangeNotifier) {
      (value as ChangeNotifier?)?.dispose();
    } else if (value is StreamController) {
      (value as StreamController?)?.close();
    }
    value = null;
  }
}

其实simple_builder.dart中还有一个SimpleBuilder不过应该还在开发

  1. ObxValue类似于.obs用法也比较简单
ObxValue((data) => Switch(
        value: data.value,
        onChanged: data, // Rx 有一个 _callable_函数! 你可以使用 (flag) => data.value = flag,
    ),
    false.obs,
),

2. 有用的提示

final name = 'GetX'.obs; //只有在值与当前值不同的情况下,才会 "更新 "流。 name.value = 'Hey';

// 所有Rx属性都是 "可调用 "的,并返回新的值。 //但这种方法不接受 "null",UI将不会重建。 name('Hello');

// 就像一个getter,打印'Hello'。 name() ;

///数字。

final count = 0.obs;

// 您可以使用num基元的所有不可变操作! count + 1;

// 注意!只有当 "count "不是final时,这才有效,除了var count += 1;

// 你也可以与数值进行比较。 count > 2;

/// booleans:

final flag = false.obs;

// 在真/假之间切换数值 flag.toggle();

/// 所有类型。

// 将 "value "设为空。 flag.nil();

// 所有的toString()、toJson()操作都会向下传递到value。 print( count ); // 在内部调用 "toString() "来GetRxInt

final abc = [0,1,2].obs; // 将值转换为json数组,打印RxList。 // 所有Rx类型都支持Json! print('json: jsonEncode(abc),type:{jsonEncode(abc)}, type: {abc.runtimeType}');

// RxMap, RxList 和 RxSet 是特殊的 Rx 类型,扩展了它们的原生类型。 // 但你可以像使用普通列表一样使用列表,尽管它是响应式的。 abc.add(12); // 将12添加到列表中,并更新流。 abc[3]; // 和Lists一样,读取索引3。

// Rx和值是平等的,但hashCode总是从值中提取。 final number = 12.obs; print( number == 12 ); // prints > true

///自定义Rx模型。

// toJson(), toString()都是递延给子代的,所以你可以在它们上实现覆盖,并直接打印()可观察的内容。

class User { String name, last; int age; User({this.name, this.last, this.age});

@override
String toString() => '$name $last, $age years old';

}

final user = User(name: 'John', last: 'Doe', age: 33).obs;

// user是 "响应式 "的,但里面的属性却不是! // 所以,如果我们改变其中的一些变量: user.value.name = 'Roi'; // 小部件不会重建! // 对于自定义类,我们需要手动 "通知 "改变。 user.refresh();

// 或者我们可以使用update()方法! user.update((value){ value.name='Roi'; });

print( user );