计算用户看到的RecyclerView项目数

时间:2018-03-15 13:49:59

标签: android android-recyclerview

我想跟踪我的应用中用户需要多少滚动条。因此,我想计算在用户采取某些行动之前已在用户屏幕上显示的回收物品项目数量。

有没有办法计算这个?也许使用可见物品&滚动位置?

我正在使用RecyclerView GridLayoutManager

2 个答案:

答案 0 :(得分:1)

我刚刚想出了一个解决方案:

var oldFirstPos = -1
var oldLastPos = -1
var totalItemsViewed = 0

with(rvBasic) {
    layoutManager = gridLayoutManager
    adapter = BasicRecyclerViewAdapter(layoutInflater, items)

    addOnScrollListener(object : RecyclerView.OnScrollListener() {
        override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
            super.onScrolled(recyclerView, dx, dy)

            val currFirstPos = gridLayoutManager.findFirstCompletelyVisibleItemPosition()
            val currLastPos = gridLayoutManager.findLastCompletelyVisibleItemPosition()

            totalItemsViewed += when (oldFirstPos) {
                -1 -> currLastPos - currFirstPos + 1
                else -> when {
                    dy > 0 -> Math.abs(currLastPos - oldLastPos) //scrolling to bottom
                    else -> Math.abs(currFirstPos - oldFirstPos) //scrolling to top
                }
            }

            oldLastPos = currLastPos
            oldFirstPos = currFirstPos

            Log.d("Items viewed", "items viewed: ${totalItemsViewed}")
        }
    })
}

我的想法如下:抓住当前firstVisibleCompletelyVisiblePositionlastCompletelyVisiblePosition,然后根据滚动方向计算自上次滚动以来这些位置的增量。通过将oldFirstPos设置为-1oldLastPos理论上可以是任何值)来识别初始滚动,因为GridLayoutManager中的位置从0开始。

要确定最初可见 - 因此查看 - 项目的数量,需要使用以下简单公式:currLastPos - currFirstPos + 1+1存在,因为位置从0开始)。

当用户现在滚动到底部dy gets greater than 0时,lastPos的绝对更改对我们很重要。当滚动方向相反时,同样适用。但是,由于关键区别,现在firstPos的绝对变化是自上次onScrolled被触发以来可见项目数量的变化。

为什么在滚动方向改变时调整位置变化计算很重要?

假设您的网格中有19个项目带有spanCount of 4,因此最后一行将包含3个项目。向下滚动,totalItemsViewed将计数到19.现在当您向上滚动时,您将错过一个项目,因为如果向上滚动一点,lastPos将从19变为16,但是firstPos会改变(取决于显示屏上一次可见的项目数量)12到8.现在你基本上丢失了一个项目。如果你的items % spanCount == 0那么你可以没有根据滚动方向调整更改。

注意:此解决方案仅适用于垂直GridLayoutManager(虽然水平相似)

答案 1 :(得分:0)

根据@Rene Ferrari的回答,我在滚动到顶部时修改了代码,您可以在Java中执行以下操作:

private int oldFirstPos = -1, oldLastPos = -1,totalItemsViewed = 0;
rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                GridLayoutManager layoutManager = ((GridLayoutManager)recyclerView.getLayoutManager());

                int currFirstPos = layoutManager.findFirstCompletelyVisibleItemPosition();
                int currLastPos = layoutManager.findLastCompletelyVisibleItemPosition();

                totalItemCount = layoutManager.getItemCount();
                if(oldFirstPos == -1){
                    totalItemsViewed += currLastPos - currFirstPos + 1;
                }else{
                    if(dy > 0){
                        totalItemsViewed += Math.abs(currLastPos - oldLastPos);
                    }else{
                        totalItemsViewed -= Math.abs(oldLastPos - currLastPos);
                    }
                }
                oldLastPos = currLastPos;
                oldFirstPos = currFirstPos;

                Log.e("totalItemsViewed",totalItemsViewed);
 }
        });