RecyclerViewのItemDecorationでStickyHeader効果を実現(メモ)

20859 ワード

最近、QQブラウザのような閲覧記録の効果をします.
次の効果です
QQブラウザは半日遊んで、少し分析しました.
以前はItemDecorationでRecyclerViewにitemの分割線を描画していました.
よく観察すると、この効果は指定したitemに分割線を描くことです.
ここには良いチュートリアルがあり、ブロガーは詳細な分析と実現を書かない.
もう一つの実装方法は、Android RecyclerViewのトップリフト実装に興味のある方は試してみてください
踏みつけた穴を重点的に説明します.
1.データ分類:
ブラウズレコードは、最新のレコードを最上位に表示する必要があるため、ブロガーは格納時に順番に格納されます.データベースをクエリーした後、コレクションを反転する必要があります.
集合の順序は逆ですが、集合中のJavaBeanのposition属性は元の(正の集合の順序)です.ではfirstとlastを判断するには
気をつけてね.
fun isFirstViewInGroup(): Boolean {//   shi     
    if (groupSize > 0) {
        return position == groupSize - 1
    } else {
        return position == 0
    }
}

fun isLastViewInGroup(): Boolean {//   shi     
    return position == 0
}

2.getItemOffSets()メソッド:
この方法は主に占有に用いられる.分割線でも図のフローティングバーでも、描画するには位置(空間)が必要です.
override fun getItemOffsets(outRect: Rect?, view: View?, parent: RecyclerView?, state: RecyclerView.State?) {
    super.getItemOffsets(outRect, view, parent, state)
    //  itemView        
    var position: Int? = parent?.getChildAdapterPosition(view)
    //  item          
    if (mCallBack != null) {
        var info = position?.let { mCallBack?.getGroupInfo(it) }
        var isFirst: Boolean? = info?.isFirstViewInGroup()
        if (isFirst!!) {
            //    header   
            outRect?.top = mHeaderHeight?.toInt()
        } else {//     
            outRect?.top = mDividerHeight
        }
    }
}

3.onDrawOver()メソッド:
名前の通り、この方法は描画が完了した後に実行されます.いくつかの位置パラメータに注意してください.
override fun onDrawOver(c: Canvas?, parent: RecyclerView?, state: RecyclerView.State?) {
    super.onDrawOver(c, parent, state)
    //     ItemView
    var childCount = parent?.childCount
    var account = 0
    while (account < childCount!!) {
        //  View
        var view = parent?.getChildAt(account)
        //  view        
        var index = parent?.getChildAdapterPosition(view)
        if (mCallBack != null) {
            var info = index?.let { mCallBack?.getGroupInfo(it) }
            var isFirst: Boolean? = info?.isFirstViewInGroup()
            var left = view?.paddingLeft
            var right = view?.width?.minus(view?.paddingRight)

            if (account != 0) {

                if (isFirst!!) {//       
                    //itemView  -header  (  )
                    var top = mHeaderHeight?.let { view?.top?.minus(it) }
                    var bottom = view?.top
                    drawHeader(c, top, right, bottom, left, info)
                }

            } else {//       itemView
                //RecyclerView     
                var top = parent?.paddingTop
                if (info?.isLastViewInGroup()!!) {
                    var groupLastTop = mHeaderHeight?.let { view?.bottom?.minus(it) }//         (  )
                    if (groupLastTop!! < top!!) {//           parent     (    )
                        top = groupLastTop?.toInt()
                    }
                }
                //    +header  (  )
                var bottom = mHeaderHeight?.let { top?.plus(it) }
                drawHeader(c, top?.toFloat(), right, bottom?.toInt(), left, info)
            }
        }
        account++
    }
}