拖动时滚动

Scroll while dragging

我有一些 TextViews 在 Kotlin 中实现了拖放,我想做的是当我在屏幕底部拖动​​一个 TextView 时,ScrollView 所在的位置, 使其向下滚动

Here is the app design.

如图所示,我想将 TextViews 从左列(组件)拖放到右列(框)中。框 LinearLayout 继续离开屏幕,关键是我不希望用户必须滚动到最后一个框 before 将某些东西从“组件”拖入其中" 线性布局。

所以为了回答我自己的问题,我找到的解决方案是:

lowerLimForScroll = (Resources.getSystem().displayMetrics.heightPixels * 0.8).toInt()

textView.setOnDragListener { boxContentView, dragEvent -> 
            
    val boxesLayoutCoords = intArrayOf(0, 0)
    // this calculates the x, y of the top left corner of the 
    // ScrollView
    boxContentView.getLocationInWindow(boxesLayoutCoords)
    when (dragEvent.action) {
        DragEvent.ACTION_DRAG_LOCATION -> {
            checkForScroll(dragEvent.y, boxesLayoutCoords[1])
    }
    true
}

同样,我也必须向 scrollView 添加一个 on Drag Listener,因为我使用了分隔线,当我离开滚动视图并悬停在属于 ScrollView 的分隔线上方时,滚动停止了

scrollView.setOnDragListener { _, dragEvent ->

    val boxesLayoutCoords = intArrayOf(0, 0)
    scrollView.getLocationInWindow(boxesLayoutCoords)

    when (dragEvent.action) {
        DragEvent.ACTION_DRAG_LOCATION -> {
            checkForScroll(dragEvent.y, boxesLayoutCoords[1])
        }              
    }
    true
}

最后是 checkForScroll 函数

private fun checkForScroll(pointerY: Float, startOfScrollView: Int) {
    /* if the upper limit is passed, meaning a pixel height, scroll up */
    if ((pointerY + startOfScrollView) < upperLimForScroll) {
        findViewById<ScrollView>(R.id.boxesScrollView).smoothScrollBy(0, -20)
    }
    /* if the lower limit is passed, meaning a pixel height, scroll down */
    else if (pointerY + startOfScrollView > lowerLimForScroll) {
        findViewById<ScrollView>(R.id.boxesScrollView).smoothScrollBy(0, 15)
    }
}