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