Flutter aspectd (四) 全埋点实现

简述

aspectd的简单原理清楚了,下面尝试实现一下全埋点,参考大佬文章:
Flutter之全埋点思考与实现

获取到点击的按钮

 @Execute("package:flutter/src/gestures/binding.dart", "GestureBinding",
      "-dispatchEvent")
  @pragma("vm:entry-point")
  dynamic hookHitTest(PointCut pointCut) {
    PointerEvent pointEvent = pointCut.positionalParams[0];
    HitTestResult hitTestResult = pointCut.positionalParams[1];
    if (pointEvent is PointerUpEvent) {
      HookImpl.getInstance().hookHitTest(hitTestResult.path.first, pointEvent);
    }
    return pointCut.proceed();
  }

上面是通过拦截,GestureBinding的dispatchEvent方法,获取到传给该方法的PointerEvent和HitTestResult参数。

拦截点击事件

  @Execute("package:flutter/src/gestures/recognizer.dart", "GestureRecognizer",
      "-invokeCallback")
  @pragma("vm:entry-point")
  dynamic hookInvokeCallback(PointCut pointCut) {
    dynamic result = pointCut.proceed();
    dynamic eventName = pointCut.positionalParams[0];
    print("GestureRecognizer:::::invokeCallback");
    HookImpl.getInstance().hookClick(eventName);
    return result;
  }

拦截GestureRecognizer中的invokeCallback方法,可以通过传递的参数,得到是不是点击状态,判断eventName == “onTap”

 void hookClick(String eventName) {
    if (eventName == "onTap") {
      initValues();
      _getElementPath();
      _getElementType();
      _getElementContent();
      _printClick(elementInfoMap);
      _resetValues();
    }
  }

定位一个Widget是否是自己写的

可以参照Flutter的track_widget_constructor_locations类进行更改,所在位置:

kernel/transformations/track_widget_constructor_locations.dart

对该类的更改:

// 判断当导入类中有我们定义的类的时候
if (importUri.path.contains('hook_impl.dart')) {
    for (Class class_ in library.classes) {
        // 获取到所有的类,如果有_CustomHasCreationLocation,那么把_hasCreationLocationClass赋值为_CustomHasCreationLocation,下面同理
      if (class_.name == '_CustomHasCreationLocation') {
        _hasCreationLocationClass = class_;
      } else if (class_.name == '_CustomLocation') {
        _locationClass = class_;
      }
    }
  }

再看看_hasCreationLocationClass做了什么

 void _transformClassImplementingWidget(Class clazz) {
    // 这里是给我们写的组件加了一个SuperType _CustomHasCreationLocation
    clazz.implementedTypes
        .add(new Supertype(_hasCreationLocationClass, <DartType>[]));
}

这样我们就可以通过判断Widget是不是_CustomHasCreationLocation类型,就能知道这个Widget是不是我们自己写的。

效果

由于大部分都是照着大佬文章实现的,所以不做过多的解析。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h1X9TLKn-1624415460402)(https://note.youdao.com/yws/api/personal/file/WEBd04954cb33c361c464d36c6e9cda04db?method=download&shareKey=aeea23a1b9adbfc1978452de8ae42c65)]

githbu地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flutter 底部弹出动画可以通过使用 BottomSheet widget 和 AnimatedContainer widget 来实现。 首先,创建一个 StatefulWidget,包含一个 bool 变量用于控制 BottomSheet 的显示和隐藏。 ``` class BottomSheetDemo extends StatefulWidget { @override _BottomSheetDemoState createState() => _BottomSheetDemoState(); } class _BottomSheetDemoState extends State<BottomSheetDemo> { bool _isVisible = false; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Bottom Sheet Demo'), ), body: Center( child: RaisedButton( child: Text('Show Bottom Sheet'), onPressed: () { setState(() { _isVisible = true; }); }, ), ), bottomSheet: _isVisible ? Container( decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.2), blurRadius: 5.0, spreadRadius: 1.0, offset: Offset(0.0, -1.0), ), ], ), child: SafeArea( child: AnimatedContainer( duration: Duration(milliseconds: 300), height: _isVisible ? 200.0 : 0.0, child: Center( child: Text('This is a Bottom Sheet'), ), ), ), ) : null, ); } } ``` 在上面的代码中,我们使用了一个 RaisedButton 来触发 Bottom Sheet 的显示,当用户点击按钮后,我们将 _isVisible 变量设置为 true,Bottom Sheet 就会显示出来。 Bottom Sheet 的内容是一个 AnimatedContainer,它的高度可以通过修改 _isVisible 变量来控制。在 AnimatedContainer 中,我们设置了一个动画时长为 300 毫秒,当 _isVisible 变量变化时,高度会从 0.0 到 200.0 进行动画过渡。 在 Bottom Sheet 的外部,我们使用了一个 Container 来包装它,并设置了一些阴影效果和背景颜色。我们还使用了 SafeArea 来确保 Bottom Sheet 不会被设备的导航栏遮挡。 通过这种方式,我们可以很容易地实现一个底部弹出动画效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值