Exposure
Exposure
Exposure 是一个很方便对 View 进行曝光埋点收集的库,不用修改现有布局实现方式,只需在现有代码上做极少量修改即可实现 View 的曝光埋点。支持判断 View 是否达到有效曝光面积,支持 RecyclerView 的线性布局、网格布局、瀑布流布局,横向滑动曝光埋点,支持对指定 View 进行曝光收集。
添加依赖:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
dependencies {
implementation 'com.github.wp529:Exposure:1.2.4'
}
使用方式:
将需要采集曝光的 View 替换为对应的曝光 View,库里面提供了三个曝光 View (ExposureLinearLayout,ExposureFrameLayout,ExposureRelativeLayout),若需其他类型的曝光 View 可以自行让对应 View 实现 IProvideExposureData 接口
<?xml version="1.0" encoding="utf-8"?> <com.wp.exposure.view.ExposureFrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/exposureRoot" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/tvText" android:layout_width="wrap_content" android:layout_height="wrap_content" tools:text="TEXT" /> </com.wp.exposure.view.ExposureLinearLayout>
为曝光 View 绑定上对应的曝光数据
//注:这里的 data 对象最好实现了 equals 方法 exposureRoot.exposureBindData = data
以下两种方式根据布局方式选择其一
RecyclerView 添加曝光收集
在给 RecyclerView 设置完 adapter 后实例化 RecyclerViewExposureHelper,必须在设置完 adapter 后才能实例化的原因是为了能让 RecyclerViewExposureHelper 在 adapter 调用更新 item 方法后可以自动计算曝光数据。实例化时需传递五个参数
- recyclerView 需要收集曝光的 RecyclerView
- exposureValidAreaPercent 判定曝光的面积,即大于这个面积才算做曝光,百分制,eg:设置为 50 item 的面积为 200 平方,则必须要展示 200 * 50% = 100 平方及以上才算为曝光
- lifecycleOwner RecyclerView 感知此生命周期组件,根据生命周期感知 RV 可见性,以便自动处理开始曝光和结束曝光,一般情况 RV 在 Activity 中传 Activity,在 Fragment 中传 Fragment
- mayBeCoveredViewList 可能会遮挡 RV 的 View 集合
- exposureStateChangeListener 曝光状态改变监听器
其他情况:若 RecyclerView 被嵌套在可滚动控件(eg:ScrollView,NestedScrollView,RecyclerView 等)中,将会导致 RecyclerViewExposureHelper 中持有的 RecyclerView 不能响应滑动的情况,就必须由外部告知 RecyclerView 滚动状态然后触发曝光收集。具体做法:给可滚动控件添加滚动监听,滚动监听中调用 recyclerViewExposureHelper.onScroll()recyclerViewExposureHelper = RecyclerViewExposureHelper( recyclerView = rvList, exposureValidAreaPercent = 50, lifecycleOwner = this, mayBeCoveredViewList = null, exposureStateChangeListener = object : IExposureStateChangeListener<String> { override fun onExposureStateChange( bindExposureData: String, position: Int, inExposure: Boolean ) { Log.i( "ListActivity", "${bindExposureData}${ if (inExposure) { "开始曝光" } else { "结束曝光" } }" ) } } )
对指定 View 添加曝光收集
实例化 ViewExposureHelper,实例化时需传递五个参数,与 RecyclerViewExposureHelper 基本一致
viewList 需要指定收集曝光的 View 集合
val helper = ViewExposureHelper( viewList = list, exposureValidAreaPercent = 50, lifecycleOwner = this, mayBeCoveredViewList = null, exposureStateChangeListener = object : IExposureStateChangeListener<String> { @SuppressLint("LongLogTag") override fun onExposureStateChange( bindExposureData: String, position: Int, inExposure: Boolean ) { Log.i( "CollectViewGroupActivity", "${bindExposureData}${ if (inExposure) { "开始曝光" } else { "结束曝光" } }" ) } } )
1.若指定收集曝光的 View 在可滚动的布局中,那么在滚动时,需调用 helper.onScroll()
2.若指定收集曝光的 View Visible 状态变更,helper.childViewVisibleChange()
3.若需动态添加指定收集曝光的 View,则需调用 helper.addViewToRecordExposure(view)
至此,曝光收集接入完成,只需在onExposureStateChange回调中进行处理即可。onExposureStateChange回调会回传三个参数。
- view 绑定的曝光数据
- 曝光状态改变的位置
- 曝光状态。曝光状态 true 代表 view 从未曝光状态进入曝光中状态,false 代表 view 从曝光中状态进入结束曝光状态
View 曝光埋点对客户端来说只用处理三个问题,此库的作用即是处理这三个问题
view 可见(开始曝光)
view 不可见(结束曝光)
view 可见面积是否为有效曝光面积
埋点 SDK 一般会提供三个 api 供客户端调用
onItemExposureStart()
onItemExposureEnd()
onItemExposureUpload()
所以只需在onExposureStateChange里调用埋点 SDK 对应的 api 即可,至于曝光时长是否为有效曝光一般由埋点 SDK 进行计算
若没有埋点 SDK,也可通过onExposureStateChange自行处理相关逻辑