2

NestedScrollView 仿照 H5 锚点实现

 1 year ago
source link: http://i.lckiss.com/?p=8115
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

NestedScrollView 仿照 H5 锚点实现

2022-09-23

因为一些原因,需要在原生仿照一个 H5 的锚点效果,很不幸的是,在一个迭代后,效果又被砍掉了,不过实现还是记录下。

由于 tab 点击以及 pager 滑动的联动代码并不优雅,需要处理那些抖动问题,那些除了代码不美观倒不是什么难题,主要记录下 ScrollView 中 View 的查找以及根据 ID 的 View 定位,当然这些也都是网络上现成可以 Copy 到的。

fun NestedScrollView.findNearestView(ids: Array<Int>): Int {
    val parentLocation = IntArray(2)
    getLocationOnScreen(parentLocation)
    val parentY = parentLocation[1]
    var pos = 0
    for (index in ids.indices) {
        val viewId = ids[index]
        val moveToView = findViewById<View>(viewId)
        val viewLocation = IntArray(2)
        moveToView.getLocationOnScreen(viewLocation)
        val childY = viewLocation[1]
        if (parentY > childY) {
            pos = index
        } else {
            break
        }
    }
    return pos
}
fun NestedScrollView.scrollToView(viewId: Int, offset: Int) {
    val moveToView = findViewById<View>(viewId)
    moveToView ?: return
    val parentLocation = IntArray(2)
    getLocationOnScreen(parentLocation)
    val viewLocation = IntArray(2)
    moveToView.getLocationOnScreen(viewLocation)
    val moveViewY = viewLocation[1] - parentLocation[1]
    val needScrollY = (moveViewY - offset)
    if (moveViewY == 0) return
    smoothScrollBy(0, needScrollY)
}

然后嵌套在 CoordinatorLayout 与 AppBarLayout 中出现的头部无法滑动的问题,主要靠这个解决:

/**
 * 解决 AppBarLayout 底部滑动后 头部无法滑动问题
 */private fun updateAppBarStatus() {
    val params: CoordinatorLayout.LayoutParams =
        mBinding.appBarLayout.layoutParams as CoordinatorLayout.LayoutParams
    val behavior = params.behavior as AppBarLayout.Behavior
    behavior.setDragCallback(object : AppBarLayout.Behavior.DragCallback() {
        override fun canDrag(@NonNull appBarLayout: AppBarLayout): Boolean = true
    })
}

在滚动后调用一次 updateAppBarStatus 更新一下状态即可。

这些东西也显得相对原始,现在用的场合并不多了,随之而来的是更多的更为复杂的多状态协调以及元素共享页面,不过目前还没有遇到那种需求。

参考:https://github.com/taixiang/tabScroll


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK