Android实战——RecyclerView条目曝光埋点
Posted callme大帅
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android实战——RecyclerView条目曝光埋点相关的知识,希望对你有一定的参考价值。
一、概要
100行代码实现recyclerview条目曝光埋点设计
二、设计思路
- 条目露出来一半以上视为该条目曝光。
- 在rv滚动过程中或者数据变更回调OnGlobalLayoutListener时,将符合条件1的条目记录在曝光列表、上传埋点集合里。
- 滚动状态变更和OnGlobalLayoutListener回调时,且列表状态为idle状态,触发上报埋点。
三、容错性
- 滑动过快时,视为未曝光
- 数据变更时,重新检测曝光
- 曝光过的条目,不会重复曝光
四、接入影响
- 对业务代码零侵入
- 对列表滑动体验无影响
五、代码实现
import android.graphics.Rect
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import java.util.*
class RVItemExposureListener(
private val mRecyclerView: RecyclerView,
private val mExposureListener: IOnExposureListener?
)
interface IOnExposureListener
fun onExposure(position: Int)
fun onUpload(exposureList: List<Int>?): Boolean
private val mExposureList: MutableList<Int> = ArrayList()
private val mUploadList: MutableList<Int> = ArrayList()
private var mScrollState = 0
var isEnableExposure = true
private var mCheckChildViewExposure = true
private val mViewVisible = Rect()
fun checkChildExposeStatus()
if (!isEnableExposure)
return
val length = mRecyclerView.childCount
if (length != 0)
var view: View?
for (i in 0 until length)
view = mRecyclerView.getChildAt(i)
if (view != null)
view.getLocalVisibleRect(mViewVisible)
if (mViewVisible.height() > view.height / 2 && mViewVisible.top < mRecyclerView.bottom)
checkExposure(view)
private fun checkExposure(childView: View): Boolean
val position = mRecyclerView.getChildAdapterPosition(childView)
if (position < 0 || mExposureList.contains(position))
return false
mExposureList.add(position)
mUploadList.add(position)
mExposureListener?.onExposure(position)
return true
private fun uploadList()
if (mScrollState == RecyclerView.SCROLL_STATE_IDLE && mUploadList.size > 0 && mExposureListener != null)
val success = mExposureListener.onUpload(mUploadList)
if (success)
mUploadList.clear()
init
mRecyclerView.viewTreeObserver.addOnGlobalLayoutListener
if (mRecyclerView.childCount == 0 || !mCheckChildViewExposure)
return@addOnGlobalLayoutListener
checkChildExposeStatus()
uploadList()
mCheckChildViewExposure = false
mRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener()
override fun onScrollStateChanged(
recyclerView: RecyclerView,
newState: Int
)
super.onScrollStateChanged(recyclerView, newState)
mScrollState = newState
uploadList()
override fun onScrolled(
recyclerView: RecyclerView,
dx: Int,
dy: Int
)
super.onScrolled(recyclerView, dx, dy)
if (!isEnableExposure)
return
// 大于50视为滑动过快
if (mScrollState == RecyclerView.SCROLL_STATE_SETTLING && Math.abs(dy) > 50)
return
checkChildExposeStatus()
)
六、使用
RVItemExposureListener(yourRecyclerView, object : RVItemExposureListener.IOnExposureListener
override fun onExposure(position: Int)
// 滑动过程中出现的条目
Log.d("exposure-curPosition:", position.toString())
override fun onUpload(exposureList: List<Int>?): Boolean
Log.d("exposure-positionList", exposureList.toString())
// 上报成功后返回true
return true
)
完结,撒花🎉
以上是关于Android实战——RecyclerView条目曝光埋点的主要内容,如果未能解决你的问题,请参考以下文章
Android RecyclerView嵌套RecyclerView
重复条目:android / support / v7 / recyclerview / extensions / ListAdapter.class [复制]