向上或向下拖动时固定ViewHolder

时间:2019-11-17 16:18:57

标签: android android-recyclerview android-nestedscrollview

我在RecyclerView的{​​{1}}中有两个linear horizontal layout,一个是显示索引,另一个是显示数据(我知道我可以在一个{ {1}},但是我只想拖放数据NestedScrollView而不是其他数据;这就是为什么我必须使用两个RecyclerView)的原因。现在,由于我希望它们一起滚动,因此将它们放置在RecyclerView内的线性水平布局中。现在,我希望它像普通的RecyclerView一样滚动。但是就像NestedScrollView中一样,我做不到。因此,我进行了坐标明智的滚动。我将要拖动的RecyclerView的y位置与NestedScrollView的滚动位置进行比较,以检查它是否传递了某个值来触发滚动。但是,这样做不会保持我的ViewHolder不变。有时会发抖。如何保持固定状态?

我尝试过的- DisplayItemTouchHelperCallback.kt

NestedScrollView

NestedScroll.kt

ViewHolder

ViewItemAdapter.kt

class DisplayItemTouchHelperCallback(
    val mAdapter: ItemTouchHelperAdapter,
    val itemRecyclerView: RecyclerView,
    val nestedScrollView: NestedScrollView,
    val fragment: ListItemFragment
) : ItemTouchHelper.Callback() {
    var height = 0
    var nestedScroll = NestedScroll()
    var isScrollable = false
    var timeDelay = 15L
    var globalSourceHeight = 0
    var sourceView: RecyclerView.ViewHolder? = null

    var holder: RecyclerView.ViewHolder? = null

    override fun isLongPressDragEnabled(): Boolean {
        return true
    }

    override fun isItemViewSwipeEnabled(): Boolean {
        return false
    }

    override fun onMove(
        recyclerView: RecyclerView,
        source: RecyclerView.ViewHolder,
        target: RecyclerView.ViewHolder
    ): Boolean {
        val currentScrollY = fragment.currentScrollY

        sourceView = source
        val sourceHeight = (source.itemView.y).toInt()

        globalSourceHeight = sourceHeight - currentScrollY

        when {
            globalSourceHeight > DRAG_DOWN_LIMIT -> {
                height = currentScrollY

                isScrollable = true
                timeDelay = 15L
                scrollDownwards()
            }
            globalSourceHeight < DRAG_UP_LIMIT -> {
                height = currentScrollY

                isScrollable = true
                timeDelay = 15L
                scrollUpwards()
            }
            else -> isScrollable = false
        }

        return true
    }

    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, i: Int) {

    }

    override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
        val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
        val swipeFlags = ItemTouchHelper.START or ItemTouchHelper.END
        return makeMovementFlags(dragFlags, swipeFlags)
    }

    override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
        super.onSelectedChanged(viewHolder, actionState)

        when (actionState) {
            ItemTouchHelper.ACTION_STATE_DRAG -> {
                holder = viewHolder
                viewHolder?.itemView?.animate()?.rotation(-3f)
            }
            ItemTouchHelper.ACTION_STATE_IDLE -> {
                isScrollable = false

                if (viewHolder == null) {
                    holder?.itemView?.animate()?.rotation(0f)
                } else {
                    viewHolder.itemView.animate()?.rotation(0f)
                }
            }
        }
    }

    override fun onMoved(
        recyclerView: RecyclerView,
        viewHolder: RecyclerView.ViewHolder,
        fromPos: Int,
        target: RecyclerView.ViewHolder,
        toPos: Int,
        x: Int,
        y: Int
    ) {
        super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y)
        mAdapter.onItemMove(fromPos, toPos)
    }

    private fun scrollDownwards() {
        if (isScrollable) {
            delayTimer()

            if (height < itemRecyclerView.measuredHeight) {
                Handler().postDelayed({
                    incrementHeight(true)

                    scrollDownwards()
                }, timeDelay)
            }
        }
    }

    private fun incrementHeight(isIncrement: Boolean) {
        if (isIncrement) {
            height += 3
        } else {
            height -= 3
        }

        nestedScroll = NestedScroll()
        nestedScroll.arrayResponse = fragment
        nestedScroll.execute(height)

        if (isIncrement) {
            sourceView?.itemView?.y = sourceView?.itemView?.y?.plus(3)!!
        } else {
            sourceView?.itemView?.y = sourceView?.itemView?.y?.minus(3)!!
        }
    }

    private fun scrollUpwards() {
        if (isScrollable) {
            delayTimer()

            if (height > 0) {
                Handler().postDelayed({
                    incrementHeight(false)
                    scrollUpwards()
                }, timeDelay)
            }
        }
    }

    private fun delayTimer() {
        if (timeDelay > 5) {
            timeDelay--
        }
    }
}

ListItemFragment.kt

class NestedScroll : AsyncTask<Int, Void, Int>() {
    var arrayResponse: ArrayResponse? = null

    override fun doInBackground(vararg oldHeight: Int?): Int {
        val height = oldHeight[0]

        if (height != null) {
            return height
        }

        return 0
    }

    override fun onPostExecute(result: Int?) {
        super.onPostExecute(result)
        val hashMap = LinkedHashMap<String, Any>()

        if (result != null) {
            hashMap["scroll"] = result
        }

        arrayResponse?.onValuePass(hashMap)
    }
}

0 个答案:

没有答案