因为一些原因,需要在原生仿照一个 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 更新一下状态即可。
这些东西也显得相对原始,现在用的场合并不多了,随之而来的是更多的更为复杂的多状态协调以及元素共享页面,不过目前还没有遇到那种需求。
以上。
本站广告由 Google AdSense 提供
0条评论