使用可观察属性动态刷新状态

113 阅读1分钟

对于很多可动态刷新的部分 我们都需要 setState 很麻烦 于是 就想用全局观察者模式去创建属性

var name = ''.os; // 就拥有了观察属性

OS(os:name,osv:()=>Text('${name.self}')),

name.value = '张三'; //这里name 就改变了

主动刷新 
name.refresh();

name 是 ValueNotifier 类型

class ObServer extends ValueNotifier {
  bool _isDispose = false; //记录是否被销毁
  bool _equalRefresh = true;//相同的时候也刷新
  ObServer(value) : super(value);
  //这里可以主动刷新
  refresh(){
    notifyListeners();
  }
  get self {
    return this.value;
  }
  BuildContext? _context;
  _setBuildContext(BuildContext ctx){
    _context = ctx;
  }
  BuildContext? get context {
    return _context;
  }
  @override
  set value(newValue) {
    if(_isDispose)return;
    if(newValue != this.value){
      super.value = newValue;
    }else{
      notifyListeners();
    }
  }
  @override
  void dispose() {
    _isDispose = true;
    super.dispose();
  }
  /// 当上一个值 和新的值相同时是否允许刷新
  set equalRefresh(bool newValue){
    _equalRefresh = value;
  }

}

extension obs on Object {
  ObServer  get os {
    return ObServer(this);
  }
}

typedef OsRefresh = Widget Function();

class OS extends StatefulWidget {
  ObServer os;
  OsRefresh osv;
  OS({required this.os,required this.osv});

  @override
  State<StatefulWidget> createState()=>_OsState();
}

class _OsState extends State<OS> {
  var _ls;
  @override
  void initState() {
    super.initState();
    _ls = (){
      if(mounted){
        setState(() {  });
      }
    };
    widget.os.addListener(_ls);
  }
  @override
  Widget build(BuildContext context) {
    widget.os._setBuildContext(context);
    return widget.osv();
  }
  @override
  void dispose() {
    widget.os.removeListener(_ls);
    super.dispose();
  }

}