Flutter跟踪与监控插件flutter_tracker_widget的使用

Flutter跟踪与监控插件flutter_tracker_widget的使用

这是一个支持滚动播放和合理曝光的组件。

开始使用

  1. pubspec.yaml 中添加依赖

    dependencies:
      flutter_tracker_widget: any
    
  2. 安装依赖

    在终端中运行:

    flutter pub get
    
  3. 导入库

    import 'package:flutter_tracker_widget/flutter_tracker_widget.dart';
    
  4. 使用示例

    下面是一个使用 TrackerScrollWidget 的完整示例。该示例展示了一个包含多个列表项的 ListView,并且每个列表项都有自己的曝光逻辑。

    import 'package:flutter/material.dart';
    import 'package:flutter_tracker_widget/flutter_tracker_widget.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      [@override](/user/override)
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key? key, this.title}) : super(key: key);
    
      final String? title;
    
      [@override](/user/override)
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      List<Color> _colors = [Colors.red, Colors.orange, Colors.yellow, Colors.green, Colors.cyan, Colors.blue, Colors.purple];
    
      [@override](/user/override)
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title ?? ''),
          ),
          body: Column(
            children: [
              TextButton(
                onPressed: () {
                  Navigator.of(context).push(
                    MaterialPageRoute(
                      builder: (_) => ListDemo(),
                    ),
                  );
                },
                child: Text('List Demo'),
              ),
            ],
          ),
        );
      }
    }
    
    class ListDemo extends StatelessWidget {
      [@override](/user/override)
      Widget build(BuildContext context) {
        return TrackerScrollWidget(
          isInViewPortCondition: (
            double deltaTop,
            double deltaBottom,
            double viewPortDimension,
          ) {
            return deltaTop < (0.5 * viewPortDimension) && deltaBottom > (0.5 * viewPortDimension);
          },
          child: ListView.builder(
            itemBuilder: (c, index) {
              return TrackerItemWidget(
                id: '$index',
                child: Container(
                  height: 200,
                  color: _colors[index % _colors.length],
                  child: Center(
                      child: Text(
                    '$index',
                    style: TextStyle(color: Colors.white),
                  )),
                ),
                displayNotifier: (
                  BuildContext context,
                  String id,
                ) {
                  print('开始曝光了 { id:$id - index:$index }');
                },
                builder: (
                  BuildContext context,
                  bool isInView,
                  Widget child,
                ) {
                  return Stack(children: [
                    child,
                    Positioned(
                      right: 0,
                      top: 0,
                      child: Text(
                        isInView ? '显示' : '',
                        style: TextStyle(color: Colors.white),
                      ),
                    )
                  ]);
                },
              );
            },
            itemCount: 100,
          ),
        );
      }
    }
    

    上述代码展示了如何使用 TrackerScrollWidgetTrackerItemWidget 来实现滚动列表的曝光跟踪。

主要功能

  1. 在滚动结束时处理可见逻辑
    避免滚动过程中频繁处理逻辑导致性能问题。

  2. 增加曝光逻辑
    支持滚动过程中只曝光一次或每次都曝光。

    /// 跟踪策略
    enum TrackerStrategy {
      only, // 只有一次
      every // 每一次
    }
    

    TrackerStrategy.only 时,曝光不会重复。

    flutter: 开始曝光了 { id:first - visiable:true }
    flutter: 开始曝光了 { id:second - visiable:true }
    

    TrackerStrategy.every 时,曝光会重复。

    flutter: 开始曝光了 { id:0 - index:0 - visiable:true }
    flutter: 开始曝光了 { id:1 - index:1 - visiable:true }
    
  3. 首次进入也会走曝光和hit逻辑
    如果想指定首次命中的视图,可以使用 initHitIds 将指定的 ID 传入。

    initHitIds: ['0'],
    
  4. 方便获取可见上下文
    底层维护一个上下文列表,便于获取 ListView 中可见的渲染对象。

  5. 更合理的释放机制
    提供更合理的资源管理机制,确保在不使用时释放资源。

示例代码

完整的示例代码可以在以下文件中查看:

import 'package:example/custom_scroll_demo.dart';
import 'package:example/list_demo.dart';
import 'package:flutter/material.dart';

import 'horizontal_list.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, this.title}) : super(key: key);

  final String? title;

  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<Color> _colors = [Colors.red, Colors.orange, Colors.yellow, Colors.green, Colors.cyan, Colors.blue, Colors.purple];

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title ?? ''),
      ),
      body: Column(
        children: [
          TextButton(
            onPressed: () {
              Navigator.of(context).push(
                MaterialPageRoute(
                  builder: (_) => ListDemo(),
                ),
              );
            },
            child: Text('List Demo'),
          ),
          TextButton(
            onPressed: () {
              Navigator.of(context).push(
                MaterialPageRoute(
                  builder: (_) => CustomScrollDemo(),
                ),
              );
            },
            child: Text('CustomScroll Demo'),
          ),
          TextButton(
            onPressed: () {
              Navigator.of(context).push(
                MaterialPageRoute(
                  builder: (_) => HorizontalList(),
                ),
              );
            },
            child: Text('Horizontal List Demo'),
          ),
        ],
      ),
    );
  }
}

更多关于Flutter跟踪与监控插件flutter_tracker_widget的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter跟踪与监控插件flutter_tracker_widget的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中集成和使用flutter_tracker_widget插件的一个示例。这个插件可以帮助你跟踪和监控小部件的状态和行为。请注意,实际使用时你需要确保已经将该插件添加到你的pubspec.yaml文件中。

首先,确保你的pubspec.yaml文件中包含以下依赖项:

dependencies:
  flutter:
    sdk: flutter
  flutter_tracker_widget: ^最新版本号  # 替换为实际最新版本号

然后运行flutter pub get来安装依赖。

接下来,在你的Flutter项目中,你可以按照以下步骤使用flutter_tracker_widget

  1. 导入插件

    在你的Dart文件中导入插件:

    import 'package:flutter_tracker_widget/flutter_tracker_widget.dart';
    
  2. 创建被跟踪的小部件

    使用TrackerWidget来包装你想要跟踪的小部件。例如,假设我们有一个简单的计数器应用:

    import 'package:flutter/material.dart';
    import 'package:flutter_tracker_widget/flutter_tracker_widget.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: Text('Flutter Tracker Widget Demo'),
            ),
            body: Center(
              child: TrackerWidget(
                child: MyCounter(),
                onBuild: (context, widget) {
                  print('MyCounter widget is being built');
                },
                onDispose: (context, widget) {
                  print('MyCounter widget is being disposed');
                },
                onChange: (context, widget, key, value) {
                  print('MyCounter state changed: $value');
                },
              ),
            ),
          ),
        );
      }
    }
    
    class MyCounter extends StatefulWidget {
      @override
      _MyCounterState createState() => _MyCounterState();
    }
    
    class _MyCounterState extends State<MyCounter> {
      int _counter = 0;
    
      void _incrementCounter() {
        setState(() {
          _counter++;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        );
      }
    }
    
  3. 处理回调

    在上面的代码中,TrackerWidget包装了MyCounter小部件,并且定义了三个回调:

    • onBuild:当小部件被构建时调用。
    • onDispose:当小部件被销毁时调用。
    • onChange:当小部件的状态改变时调用(注意:onChange回调需要手动触发,插件本身不会自动检测状态变化,这通常通过包装状态或使用Provider等状态管理库来实现)。

    注意:在这个示例中,onChange回调没有实际触发,因为flutter_tracker_widget不会自动检测到_counter的变化。要实现这一点,你可能需要结合使用状态管理库(如Provider)或者手动触发回调。

  4. 手动触发状态变化(可选)

    如果你想要手动触发状态变化回调,可以在状态改变时调用一个自定义函数,例如:

    class _MyCounterState extends State<MyCounter> {
      int _counter = 0;
      TrackerController _trackerController;
    
      @override
      void initState() {
        super.initState();
        _trackerController = TrackerController();
      }
    
      void _incrementCounter() {
        setState(() {
          _counter++;
          _trackerController.trackChange('counter', _counter);
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return TrackerWidget(
          controller: _trackerController,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'You have pushed the button this many times:',
              ),
              Text(
                '$_counter',
                style: Theme.of(context).textTheme.headline4,
              ),
            ],
          ),
          onChange: (context, widget, key, value) {
            print('State changed: $key = $value');
          },
        );
      }
    
      @override
      void dispose() {
        _trackerController.dispose();
        super.dispose();
      }
    }
    

    在这个修改后的示例中,我们创建了一个TrackerController实例,并在状态改变时调用_trackerController.trackChange方法来手动触发onChange回调。

请根据你的具体需求调整这些代码。注意,由于flutter_tracker_widget的具体API和实现可能会有所不同,因此请参考插件的官方文档以获取最新和最准确的信息。

回到顶部