likes
comments
collection
share

UME: Widget层级展示

作者站长头像
站长
· 阅读数 3

Widget层级展示

今天我们来看下UME中的Widget层级展示是如何实现的

先来看一下这个功能是什么样子的, 点击某个widget,会跳转到childenElements页面

UME: Widget层级展示

当我们点击某个element时会跳进一个详情页面

UME: Widget层级展示

果不其然在widget_detail_inspector.dart这个文件中我们看到了熟悉的代码

void _inspectAt(Offset? position) {
  final List<RenderObject> selected = HitTest.hitTest(position);
  setState(() {
    selection.candidates = selected;
  });
}

还记得这个方法是干嘛的么,没错就是获取所有包含点击位置的widget,那么接下来要做的就是把这些数据显示成一个列表,再往下看在__InfoPageState中传入了selection.currentElement!.debugGetDiagnosticChain()并将element转换成了detailmodel,

搜索通过RegExp中的hasMatch方法进行匹配文字

var regExp = RegExp("$query", caseSensitive: false);
if (regExp.hasMatch(model.element.widget.toStringShort())) {
  infoList.add(model);
}

点击element后会走到_DetailContent创建详情页的布局,其中使用了一个FutureBuilder进行异步创建,并写了一个异步方法getInfo

Future<List<String>> getInfo() async {
  Completer<List<String>> completer = Completer();
  String string = element.renderObject!.toStringDeep();
  List<String> list = string.split("\n");
  completer.complete(list);
  return completer.future;
}

将renderOject转成字符串并分割成数组通过list进行显示。

UME的层级展示还是比较简单的,额外在讲一下FutureBuilder这个组件

FutureBuilder

简单介绍及例子

这个组件还是比较简单的内容也比较少,先看下构造函数

const FutureBuilder({
  Key? key,
  this.future,
  this.initialData,
  required this.builder,
}) : assert(builder != null),
     super(key: key);

只有三个参数futureinitialDatabuilder,future就是我们需要传入的异步方法,initialData是用来初始化的数据,也可以不用传入,builder是用来返回future结果的,接下来我们看个例子

new FutureBuilder<String>(
  future: _calculation, // 用户定义的需要异步执行的代码,类型为Future<String>或者null的变量或函数
  builder: (BuildContext context, AsyncSnapshot<String> snapshot) {      //snapshot就是_calculation在时间轴上执行过程的状态快照
    switch (snapshot.connectionState) {
      case ConnectionState.none: return new Text('Press button to start');    //如果_calculation未执行则提示:请点击开始
      case ConnectionState.waiting: return new Text('Awaiting result...');  //如果_calculation正在执行则提示:加载中
      default:    //如果_calculation执行完毕
        if (snapshot.hasError)    //若_calculation执行出现异常
          return new Text('Error: ${snapshot.error}');
        else    //若_calculation执行正常完成
          return new Text('Result: ${snapshot.data}');
    }
  },
)

snapshot.connectionState就是异步函数future的执行状态,总共有四种执行状态: 1.ConnectionState.none 未开始 2.ConnectionState.active (还未使用过,后续学习一下) 3.ConnectionState.waiting 加载中 4.ConnectionState.done 加载完毕

防重绘

如果FutureBuilder的父组件重绘,那么FutureBuilder也会进行重绘,也会导致异步方法被重新调用,引起资源浪费,通过查看源码可以发现FutureBuilder的重绘机制是通过future是否相等进行控制的,那么如果我们传入额future是不变的就可以防止FutureBuilder进行重绘,所以我们可以引入一个变量来接口future方法,并将变量传入FutureBuilder

var _mFuture;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _mFuture = _future();
  }

 _future() async{
    ...
  }

FutureBuilder(
	future: _mFuture,
	...
)

好了今天的源码查看就到这了, 作为Flutter届的一个小学生,希望大家多多指教,有问题的地方一起讨论

转载自:https://juejin.cn/post/7026321246975442958
评论
请登录