Paging LoadRange Не вызывается после аннулирования данных в готовом - PullRequest
1 голос
/ 21 января 2020

У меня была проблема с PositionalDataSource, если loadRange не вызывался после того, как я объявил недействительным источник данных, эта проблема возникает, только если я добавляю оформление элемента для моего recyclerview для липкого заголовка
Без оформления элемента для работ recyclerview штраф
Вот мой источник данных

 override fun loadInitial(params: LoadInitialParams, callback: LoadInitialCallback<SomeData>) {

            getData(0, params.requestedLoadSize)
                    .doOnSubscribe {
                        loading.set(true)
                    }
                    .map {
                        callback.onResult(it.data, 0)
                    }
                    .doOnComplete {
                        loading.set(false)
                    }
                    .subscribe()
                    .addTo(disposal)

    }

    override fun loadRange(params: LoadRangeParams, callback: LoadRangeCallback<SomeData>) {


            getData(params.startPosition, params.loadSize)
                    .doOnSubscribe {
                        loading.set(true)
                    }
                    .map {
                        callback.onResult(it.data)
                    }
                    .doOnComplete {
                        loading.set(false)
                    }
                    .subscribe()
                    .addTo(disposal)

    }

Я делаю недействительным источник данных из getData(int,int)

Вот мой класс украшения элемента липкого заголовка

class StickyHeaderItemDecoration constructor(listener : StickyHeader) : RecyclerView.ItemDecoration() {

    private val mListener: StickyHeader = listener
    private var mStickyHeaderHeight = 0

    override fun onDrawOver(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        super.onDrawOver(canvas, parent, state)
        val topChild = parent.getChildAt(0) ?: return
        val topChildPosition = parent.getChildAdapterPosition(topChild)
        if (topChildPosition == RecyclerView.NO_POSITION) {
            return
        }
        val headerPos = mListener.getHeaderPositionFor(topChildPosition)
        val currentHeader = getHeaderViewForItem(headerPos, parent)
        fixLayoutSize(parent, currentHeader)
        val contactPoint = currentHeader.bottom
        val childInContact = getChildInContact(parent, contactPoint, headerPos)
        if (childInContact != null && mListener.isHeaderView(
                        parent.getChildAdapterPosition(
                                childInContact
                        )
                )
        ) {
            moveHeader(canvas, currentHeader, childInContact)
            return
        }
        drawHeader(canvas, currentHeader)
    }

    private fun getHeaderViewForItem(headerPosition: Int, parent: RecyclerView): View {
        val layoutResId = mListener.getHeaderLayoutIdFor(headerPosition)
        val header =
                LayoutInflater.from(parent.context).inflate(layoutResId, parent, false)
//        mListener.bindHeaderData(header, headerPosition)
        return header
    }

    private fun drawHeader(c: Canvas, header: View) {
        c.save()
        c.translate(0F, 0F)
        header.draw(c)
        c.restore()
    }

    private fun moveHeader(c: Canvas, currentHeader: View, nextHeader: View) {
        c.save()
        c.translate(0F, (nextHeader.top - currentHeader.height)*1.0F)
        currentHeader.draw(c)
        c.restore()
    }

    private fun getChildInContact(
            parent: RecyclerView,
            contactPoint: Int,
            currentHeaderPos: Int
    ): View? {
        var childInContact: View? = null
        for (i in 0 until parent.childCount) {
            var heightTolerance = 0
            val child = parent.getChildAt(i)
            //measure height tolerance with child if child is another header
            if (currentHeaderPos != i) {
                val isChildHeader =
                        mListener.isHeaderView(parent.getChildAdapterPosition(child))
                if (isChildHeader) {
                    heightTolerance = mStickyHeaderHeight - child.height
                }
            }
            //add heightTolerance if child top be in display area
            var childBottomPosition: Int
            childBottomPosition = if (child.top > 0) {
                child.bottom + heightTolerance
            } else {
                child.bottom
            }
            if (childBottomPosition > contactPoint) {
                if (child.top <= contactPoint) { // This child overlaps the contactPoint
                    childInContact = child
                    break
                }
            }
        }
        return childInContact
    }

    /**
     * Properly measures and layouts the top sticky header.
     * @param parent ViewGroup: RecyclerView in this case.
     */
    private fun fixLayoutSize(
            parent: ViewGroup,
            view: View
    ) { // Specs for parent (RecyclerView)
        val widthSpec =
                View.MeasureSpec.makeMeasureSpec(parent.width, View.MeasureSpec.EXACTLY)
        val heightSpec =
                View.MeasureSpec.makeMeasureSpec(parent.height, View.MeasureSpec.UNSPECIFIED)
        // Specs for children (headers)
        val childWidthSpec = ViewGroup.getChildMeasureSpec(
                widthSpec,
                parent.paddingLeft + parent.paddingRight,
                view.layoutParams.width
        )
        val childHeightSpec = ViewGroup.getChildMeasureSpec(
                heightSpec,
                parent.paddingTop + parent.paddingBottom,
                view.layoutParams.height
        )
        view.measure(childWidthSpec, childHeightSpec)
        view.layout(
                0,
                0,
                view.measuredWidth,
                view.measuredHeight.also { mStickyHeaderHeight = it }
        )
    }


}

Кто-нибудь может догадаться, в чем может быть проблема?

...