RecyclerViewで表示されているセルの高さを取得する

RecyclerViewのセル（下画像の赤枠部分）の`height`と`width`の表示されている比率を取得する必要があり、参考になる記事が少なかったため投稿します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484337/703e5afd-e643-013b-f0fa-58f88616dbcc.png" width=40%>

### 比率計算処理の関数を実装
今回はRecyclerViewがスクロールされた際に、表示されている全てのセルの比率をログとして出力する方針で実装していきます。


```kotlin
fun getVisibleCellHeight(rv: RecyclerView) {
        val layoutManager = rv.layoutManager as GridLayoutManager
       
        val firstPosition = layoutManager.findFirstVisibleItemPosition()
        val lastPosition = layoutManager.findLastVisibleItemPosition()
        val rvRect = Rect()
        rv.getGlobalVisibleRect(rvRect)
        for (i in firstPosition..lastPosition) {
            val rowRect = Rect()
            val currentPosition = layoutManager.findViewByPosition(i) ?: return
            currentPosition.getGlobalVisibleRect(rowRect)

            var percentHeight = if (rowRect.bottom >= rvRect.bottom) {
                val visibleHeightFirst: Int = rvRect.bottom - rowRect.top
                visibleHeightFirst * 100F / currentPosition.height
            } else {
                val visibleHeightFirst: Int = rowRect.bottom - rvRect.top
                visibleHeightFirst * 100F / currentPosition.height
            }

            var percentWidth = if (rowRect.left != 0) {
                val visibleWidth = rvRect.right - rowRect.left
                visibleWidth * 100F / currentPosition.width
            } else {
                val visibleWidth = rowRect.right - rvRect.left
                visibleWidth * 100F / currentPosition.width
            }

            if (percentHeight > 100F) {
                percentHeight = 100F
            } else if (percentHeight < 0F) {
                percentHeight = 0F
            }
            if (percentWidth > 100F) percentWidth = 100F

            Log.d("cell_ratio", "percentHeight:$percentHeight, percentWidth:$percentWidth")
        }
    }
```

以下のコードで現在見えているセルのポジションを取得します。
```.kt
val firstPosition = layoutManager.findFirstVisibleItemPosition()
val lastPosition = layoutManager.findLastVisibleItemPosition()
```

`rvRect`は大元のRecyclerView（青枠）の座標を取得し、`rowRect`はセル（赤枠）の座標を取得しています。
それらの座標を利用してそれぞれのセルの`height`と`width`の比率を計算しています。
```kotlin
val rvRect = Rect()
rv.getGlobalVisibleRect(rvRect)
for (i in firstPosition..lastPosition) {
            val rowRect = Rect()
            val currentPosition = layoutManager.findViewByPosition(i) ?: return
            currentPosition.getGlobalVisibleRect(rowRect)
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484337/8147ecf7-5875-60dc-b016-73875aa988c9.png" width=40%>

### 関数を呼び出す
RecyclerViewのスクロール止まったら先ほどの関数を呼びます。

```MainActivity.kt
binding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    getVisibleCellHeight(recyclerView, true)
                }
            }
        })
```

以下の画像のような状態でスクロールを止めるとポシション`9`,`10`の`height`の比率が59%となっており、画面表示されているセルの比率が取得されているかと思います。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484337/703e5afd-e643-013b-f0fa-58f88616dbcc.png" width=40%>

```
2022-06-06 18:20:10.275 432-432/com.example.visiblecellculc D/cell_ratio: position:1, percentHeight:100.0, percentWidth:100.0
2022-06-06 18:20:10.275 432-432/com.example.visiblecellculc D/cell_ratio: position:2, percentHeight:100.0, percentWidth:100.0
2022-06-06 18:20:10.275 432-432/com.example.visiblecellculc D/cell_ratio: position:3, percentHeight:100.0, percentWidth:100.0
2022-06-06 18:20:10.275 432-432/com.example.visiblecellculc D/cell_ratio: position:4, percentHeight:100.0, percentWidth:100.0
2022-06-06 18:20:10.275 432-432/com.example.visiblecellculc D/cell_ratio: position:5, percentHeight:100.0, percentWidth:100.0
2022-06-06 18:20:10.275 432-432/com.example.visiblecellculc D/cell_ratio: position:6, percentHeight:100.0, percentWidth:100.0
2022-06-06 18:20:10.275 432-432/com.example.visiblecellculc D/cell_ratio: position:7, percentHeight:100.0, percentWidth:100.0
2022-06-06 18:20:10.275 432-432/com.example.visiblecellculc D/cell_ratio: position:8, percentHeight:100.0, percentWidth:100.0
2022-06-06 18:20:10.275 432-432/com.example.visiblecellculc D/cell_ratio: position:9, percentHeight:59.420288, percentWidth:100.0
2022-06-06 18:20:10.275 432-432/com.example.visiblecellculc D/cell_ratio: position:10, percentHeight:59.420288, percentWidth:100.0
```

### 参考記事
https://stackoverflow.com/questions/39503595/how-to-find-percentage-of-each-visible-item-in-recycleview