Android实战——RecyclerView条目曝光埋点

Posted callme大帅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android实战——RecyclerView条目曝光埋点相关的知识,希望对你有一定的参考价值。

一、概要

100行代码实现recyclerview条目曝光埋点设计

二、设计思路

  1. 条目露出来一半以上视为该条目曝光。
  2. 在rv滚动过程中或者数据变更回调OnGlobalLayoutListener时,将符合条件1的条目记录在曝光列表、上传埋点集合里。
  3. 滚动状态变更和OnGlobalLayoutListener回调时,且列表状态为idle状态,触发上报埋点。

三、容错性

  1. 滑动过快时,视为未曝光
  2. 数据变更时,重新检测曝光
  3. 曝光过的条目,不会重复曝光

四、接入影响

  1. 对业务代码零侵入
  2. 对列表滑动体验无影响

五、代码实现

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条目曝光埋点

Android实战——RecyclerView条目曝光埋点

Android RecyclerView嵌套RecyclerView

处理RecyclerView的条目点击和多选

重复条目:android / support / v7 / recyclerview / extensions / ListAdapter.class [复制]

android控件recyclerview清空问题