如何在recycleview中查找每个可见项的百分比

时间:2016-09-15 05:18:50

标签: android android-recyclerview

int findFirstVisibleItemPosition();
int findFirstCompletelyVisibleItemPosition();
int findLastVisibleItemPosition();
int findLastCompletelyVisibleItemPosition();

所有这些方法都是提供哪些项目可见,但如何在Recycleview中查找可见项目的百分比?

即findFirstVisibleItemPosition();给出第一个可见项目的位置,但是当第一个可见时超过50个百分点时,我想执行一些操作

4 个答案:

答案 0 :(得分:12)

覆盖recyclerview的ScrollChangedListener并在onScollerdChanged中添加以下代码,以获取行的可见性。

           if (rvPercentage != null){
                LinearLayoutManager layoutManager = ((LinearLayoutManager) rvPercentage.getLayoutManager());

                final int firstPosition = layoutManager.findFirstVisibleItemPosition();
                final int lastPosition = layoutManager.findLastVisibleItemPosition();

                Rect rvRect = new Rect();
                rvPercentage.getGlobalVisibleRect(rvRect);

                for (int i = firstPosition; i <= lastPosition; i++) {
                    Rect rowRect = new Rect();
                    layoutManager.findViewByPosition(i).getGlobalVisibleRect(rowRect);

                    int percentFirst;
                    if (rowRect.bottom >= rvRect.bottom){
                        int visibleHeightFirst =rvRect.bottom - rowRect.top;
                        percentFirst = (visibleHeightFirst * 100) / layoutManager.findViewByPosition(i).getHeight();
                    }else {
                        int visibleHeightFirst = rowRect.bottom - rvRect.top;
                        percentFirst = (visibleHeightFirst * 100) / layoutManager.findViewByPosition(i).getHeight();
                    }

                    if (percentFirst>100)
                        percentFirst = 100;

                    mData.get(i).setPercentage(percentFirst);
                    mAdapter.notifyItemChanged(i);
                }
            }

它给你以下输出:

enter image description here

答案 1 :(得分:5)

您需要为addOnScrollListener()编写recyclerview并在其中写下以下代码,您将获得firstVisibleItem的位置,然后您可以在每个滚动条上获得该项目的维度。只需将以前的维度保存在全局变量中,并将其与当前维度进行比较,并计算每次滚动更改的百分比。当你得到所需的百分比然后执行你的操作。

int position = linearLayoutManager.findFirstVisibleItemPosition();
Rect rect = new Rect();
linearLayoutManager.findViewByPosition(position).getGlobalVisibleRect(rect);

答案 2 :(得分:2)

这是一个改进的(更有效,更少内存使用,更少代码,更新ViewHolder及其可见性的当前范围)Kotlin Vishal Sanghani's answer版本:

recycler.addOnScrollListener(object : RecyclerView.OnScrollListener() {
    override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
        val layoutManager = recycler.layoutManager as LinearLayoutManager
        val firstPosition = layoutManager.findFirstVisibleItemPosition()
        val lastPosition = layoutManager.findLastVisibleItemPosition()

        val globalVisibleRect = Rect()
        val itemVisibleRect = Rect()

        recycler.getGlobalVisibleRect(globalVisibleRect)

        for (pos in firstPosition..lastPosition) {
            val view = layoutManager.findViewByPosition(pos)
            if (view != null && view.height > 0 && view.getGlobalVisibleRect(itemVisibleRect)) {
                val visibilityExtent = if (itemVisibleRect.bottom >= globalVisibleRect.bottom) {
                    val visibleHeight = globalVisibleRect.bottom - itemVisibleRect.top
                    Math.min(visibleHeight.toFloat() / view.height, 1f)
                } else {
                    val visibleHeight = itemVisibleRect.bottom - globalVisibleRect.top
                    Math.min(visibleHeight.toFloat() / view.height, 1f)
                }

                val viewHolder = recycler.findViewHolderForAdapterPosition(pos) as ViewHolder
                viewHolder.setVisibilityExtent(visibilityExtent)

                // if percentage is needed...
                val percentage = visibilityExtent * 100

            }
        }
    }
})

答案 3 :(得分:0)

在Kotlin中,此功能得到了更好的改进,并且更加简单(更有效,内存使用量更少,代码更少)。

无需将rect与回收站视图rect进行比较

recycler.addOnScrollListener(object : RecyclerView.OnScrollListener() {
    override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
        val layoutManager = recycler.layoutManager as LinearLayoutManager
        val firstPosition = layoutManager.findFirstVisibleItemPosition()
        val lastPosition = layoutManager.findLastVisibleItemPosition()

       val globalVisibleRect = Rect()
       recycler.getGlobalVisibleRect(globalVisibleRect)
       for (pos in firstPosition..lastPosition) {
          val view = layoutManager.findViewByPosition(pos)
          if (view != null) {
              val percentage = getVisibleHeightPercentage(view)
          }
       }
   }

    //Method to calculate how much of the view is visible
    private fun getVisibleHeightPercentage(view: View): Double {

        val itemRect = Rect()
        val isParentViewEmpty = view.getLocalVisibleRect(itemRect)

       // Find the height of the item.
       val visibleHeight = itemRect.height().toDouble()
       val height = view.getMeasuredHeight()

       val viewVisibleHeightPercentage = visibleHeight / height * 100

       if(isParentViewEmpty){
          return viewVisibleHeightPercentage
       }else{
           return 0.0
        }
     }
})