“这是我参与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. 局部状态组件
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"),
),
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不过应该还在开发
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: {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 );