Flutter曝光追踪插件flutter_exposure的使用

Flutter曝光追踪插件flutter_exposure的使用

特性

A Flutter 点对点解决方案,目前支持滚动控件的曝光检测。

  • 滚动曝光:可以在所有滚动控件中使用,如 ListViewGridViewCustomScrollView 等。

开始使用

1. 添加依赖

在项目的 pubspec.yaml 文件中添加以下依赖:

dependencies:
  flutter_exposure: ^0.0.2

2. 安装依赖

通过命令行安装依赖:

$ flutter pub get

3. 导入包

在 Dart 文件中导入 flutter_exposure 包:

import 'package:exposure/exposure.dart';

使用方法

ScrollView 上包裹 ScrollDetailProvider 小部件,然后在需要监控曝光的小部件上包裹 Exposure。当小部件进入用户视野时,可以通过 onExpose 回调函数获取通知。

如果希望在滚动停止后再检测曝光,可以将 ScrollDetailProviderlazy 属性设置为 true

还可以通过 exposeFactor 参数控制需要曝光的比例,默认值为 0.5(即至少有一半的小部件可见时触发)。

以下是一个完整的示例代码:

ScrollDetailProvider(
    lazy: true,                     // 默认值为 false
    child: ListView.builder(
        itemCount: 200,
        itemBuilder: (context, index) {
            return Exposure(
                exposeFactor: 0.9,  // 设置为 0.9 表示需要 90% 可见才触发
                onExpose: () {      // 曝光回调
                    debugPrint('$index');
                },
                onHide: (duration) { // 隐藏回调
                    debugPrint('$duration');
                },
                child: Text('$index'), // 曝光目标小部件
            );
        },
    ),
)

示例代码

以下是完整的示例代码,展示了如何使用 flutter_exposure 插件进行曝光追踪。

1. StaggeredGridViewDemo 示例

class StaggeredGridViewDemo extends StatelessWidget {
  StaggeredGridViewDemo({Key? key}) : super(key: key);
  final ScrollController _scrollController = ScrollController();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return ScrollDetailProvider(
      lazy: false, // 不懒加载
      child: StaggeredGridView.countBuilder(
          shrinkWrap: true,
          controller: _scrollController,
          crossAxisCount: 4,
          crossAxisSpacing: 4,
          mainAxisSpacing: 10,
          itemCount: 30,
          itemBuilder: (context, index) {
            return Exposure(
              exposeFactor: 0, // 100% 可见才触发
              onExpose: () {
                debugPrint('$index'); // 打印曝光的索引
              },
              child: Container(
                  color: Colors.green,
                  child: Center(
                    child: CircleAvatar(
                      backgroundColor: Colors.white,
                      child: Text('$index'),
                    ),
                  )),
            );
          },
          staggeredTileBuilder: (index) =>
              StaggeredTile.count(2, index == 0 ? 2.5 : 3)),
    );
  }
}

2. CustomScrollViewDemo 示例

class CustomScrollViewDemo extends StatelessWidget {
  const CustomScrollViewDemo({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Material(
      child: ScrollDetailProvider(
        child: CustomScrollView(
          slivers: <Widget>[
            SliverPadding(
              padding: const EdgeInsets.all(8.0),
              sliver: SliverGrid(
                // Grid
                gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 2, // 按两列显示
                  mainAxisSpacing: 10.0,
                  crossAxisSpacing: 10.0,
                  childAspectRatio: 4.0,
                ),
                delegate: SliverChildBuilderDelegate(
                  (BuildContext context, int index) {
                    // 创建子widget
                    return Exposure(
                        onExpose: () {
                          debugPrint('SliverGrid$index'); // 打印网格曝光索引
                        },
                        child: Container(
                          alignment: Alignment.center,
                          color: Colors.cyan[100 * (index % 9)],
                          child: Text('grid item $index'),
                        ));
                  },
                  childCount: 20,
                ),
              ),
            ),
            SliverFixedExtentList(
              itemExtent: 50.0,
              delegate: SliverChildBuilderDelegate(
                (BuildContext context, int index) {
                  // 创建列表项
                  return Exposure(
                    onExpose: () {
                      debugPrint('SliverFixedExtentList:$index'); // 打印固定高度列表的曝光索引
                    },
                    child: Container(
                      alignment: Alignment.center,
                      color: Colors.lightBlue[100 * (index % 9)],
                      child: Text('list item $index'),
                    ),
                  );
                },
                childCount: 20,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

更多关于Flutter曝光追踪插件flutter_exposure的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter曝光追踪插件flutter_exposure的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


flutter_exposure 是一个用于 Flutter 应用中的曝光追踪插件。它可以帮助开发者追踪某个 Widget 在屏幕上是否被用户看到(即是否曝光)。这对于需要统计用户行为、广告展示等场景非常有用。

以下是 flutter_exposure 插件的基本使用方法:

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 flutter_exposure 依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_exposure: ^0.1.0  # 请根据实际情况使用最新版本

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

2. 导入包

在需要使用 flutter_exposure 的文件中导入包:

import 'package:flutter_exposure/flutter_exposure.dart';

3. 使用 Exposure Widget

Exposure 是一个 Widget,它包裹你想要追踪曝光的子 Widget。当这个子 Widget 在屏幕上可见时,Exposure 会触发回调。

Exposure(
  onExposureChange: (bool isExposed) {
    if (isExposed) {
      print('Widget is exposed!');
      // 在这里处理曝光逻辑,例如发送事件到分析平台
    } else {
      print('Widget is no longer exposed.');
    }
  },
  child: Container(
    width: 200,
    height: 200,
    color: Colors.blue,
    child: Center(
      child: Text('Exposure Tracking'),
    ),
  ),
);

4. 配置曝光条件

你可以通过 threshold 参数来配置曝光的条件。threshold 表示 Widget 在屏幕上可见的比例,默认是 0.5,即 Widget 至少有一半在屏幕上可见时才会触发曝光。

Exposure(
  threshold: 0.8,  // 80% 的 Widget 在屏幕上可见时才触发曝光
  onExposureChange: (bool isExposed) {
    if (isExposed) {
      print('Widget is exposed!');
    } else {
      print('Widget is no longer exposed.');
    }
  },
  child: Container(
    width: 200,
    height: 200,
    color: Colors.blue,
    child: Center(
      child: Text('Exposure Tracking'),
    ),
  ),
);

5. 处理多次曝光

默认情况下,Exposure 会在每次 Widget 进入或退出屏幕时触发回调。如果你只希望在 Widget 第一次曝光时触发回调,可以在回调中自行处理逻辑。

bool hasBeenExposed = false;

Exposure(
  onExposureChange: (bool isExposed) {
    if (isExposed && !hasBeenExposed) {
      hasBeenExposed = true;
      print('Widget is exposed for the first time!');
    }
  },
  child: Container(
    width: 200,
    height: 200,
    color: Colors.blue,
    child: Center(
      child: Text('Exposure Tracking'),
    ),
  ),
);

6. 其他注意事项

  • flutter_exposure 依赖于 Flutter 的 WidgetsBindingObserver 来监听 Widget 的可见性变化,因此它不会增加额外的性能开销。
  • 如果 Widget 在屏幕上不可见(例如被其他 Widget 遮挡),Exposure 会触发 onExposureChange(false) 回调。

7. 示例代码

以下是一个完整的示例代码:

import 'package:flutter/material.dart';
import 'package:flutter_exposure/flutter_exposure.dart';

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Exposure Example'),
        ),
        body: SingleChildScrollView(
          child: Column(
            children: [
              SizedBox(height: 1000),  // 添加一些空白区域以滚动
              Exposure(
                onExposureChange: (bool isExposed) {
                  if (isExposed) {
                    print('Widget is exposed!');
                  } else {
                    print('Widget is no longer exposed.');
                  }
                },
                child: Container(
                  width: 200,
                  height: 200,
                  color: Colors.blue,
                  child: Center(
                    child: Text('Exposure Tracking'),
                  ),
                ),
              ),
              SizedBox(height: 1000),  // 添加一些空白区域以滚动
            ],
          ),
        ),
      ),
    );
  }
}
回到顶部