使用StaggeredGridLayout

问题描述

所以这很棘手。我发现最有效的方法是对该answer进行修改。在我将最后一个项目设为与视图相同的高度的地方,我要全角且不可见。然后,我添加一个itemdecoration,并将其绘制在列表中最后一个项目应该可见的位置,如下所示:

class Stickydecoration (private val stickyView: View) : Itemdecoration() {

    override fun onDraw(c: Canvas,parent: RecyclerView,state: RecyclerView.State) {
        super.onDraw(c,parent,state)

        // layout basically just gets drawn on the reserved space on top of the first view
        stickyView.layout(parent.left,parent.right,stickyView.measuredHeight)
        for (i in 0 until parent.childCount) {
            val view: View = parent.getChildAt(i)
            if (parent.getChildAdapterPosition(view) == parent.childCount - 1) {
                c.save()

                val rectf = Rect()
                view.getGlobalVisibleRect(rectf)
                c.translate(0f,(rectf.top).toFloat())

                stickyView.draw(c)
                c.restore()
                break
            }
        }
    }

    override fun getItemOffsets(outRect: Rect,view: View,state: RecyclerView.State) {
        outRect.setEmpty()
    }
}

这种方法的问题是,当recyclerview中最后一个项目上方的项目从视图中消失时,rectf.topview.top的值或我可以想到的任何度量值都会发生跳跃并替换最后一项。

有人知道使用StaggeredGridLayoutManager将全宽的最后一项或页脚添加到recyclerview的方法吗?我知道它可以与Gridlayout一起使用,但就我而言,它不是一个选择。

或者,如果您知道一个值可以正确显示屏幕上最后一项的位置而没有任何值跳动?

编辑:

我想要实现的更多细节。

enter image description here

它应该是一个StaggeredGridLayout,在最后一项下方有一个页脚,该页脚是全角,并与其余内容一起滚动。

解决方法

在适配器中,您可以像这样为页脚UI添加条件:

@Override
    public int getItemViewType(int position) {
        if (// normal UI) {
            return VIEW_TYPE_NORMAL;
        } else {
            return VIEW_TYPE_FOOTER;
        }
    }

并在 onBindViewHolder 中为 VIEW_TYPE_FOOTER 添加这样的内容。

StaggeredGridLayoutManager.LayoutParams layoutParams =
                        (StaggeredGridLayoutManager.LayoutParams) ((YourViewHolder) holderType).itemView.getLayoutParams();
                /*
                 * to make View to occupy full width of the parent
                 */
                layoutParams.setFullSpan(true);
,

要使用StaggeredGridLayoutManager在recyclerView中创建全宽页脚,可以执行以下操作。创建一个自定义的ItemDecoration:

class FooterDecoration (private val footerView: View) : ItemDecoration() {

    override fun onDraw(c: Canvas,parent: RecyclerView,state: RecyclerView.State) {
        super.onDraw(c,parent,state)

        footerView.layout(parent.left,parent.right,footerView.measuredHeight)
        val count = parent.adapter!!.itemCount

        val view: View = parent.getChildAt(parent.childCount - 1)
        if (parent.getChildAdapterPosition(view) == count - 1) {
            c.save()

            val rect = Rect()
            view.getGlobalVisibleRect(rect)
            c.translate(0f,(rect.top).toFloat())

            footerView.draw(c)
            c.restore()
        }
    }
}

然后在您的recyclerView中将您要使用的视图膨胀并添加为项装饰:

recyclerView.apply {
    val footerView: View = LayoutInflater.from(context).inflate(R.layout.item_footer_placeholder,this,false)
    val measureSpec = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED)
    footerView.measure(measureSpec,measureSpec)
    addItemDecoration(ServicesFooterDecoration(footerView))

}
,

onBindViewHolder 中使用 isFullSpan

override fun onBindViewHolder(holder: LoadStateViewHolder,loadState: LoadState) {
        holder.bind(loadState)
        val layoutParams = holder.itemView.layoutParams as StaggeredGridLayoutManager.LayoutParams
        layoutParams.isFullSpan = true
    }