制作一个锚点定位的ScrollView,你有过迷茫吗

val viewLocation = IntArray(2)
moveToView.getLocationOnScreen(viewLocation)
//坐标相减得到要滚动的距离
val moveViewY = viewLocation[1] - parentLocation[1]
//加上偏移坐标量,得到最终要滚动的距离
val needScrollY = (moveViewY - offset)
//如果是0,那就没必要滚动了,说明坐标已经重合了
if (moveViewY == 0) return
smoothScrollBy(0, needScrollY)
}

这里的offset参数是滚动的额外偏移量。来保证滚动的时候预留一些额外空间。

//滚动到第一个View
fun scrollView1(view: View) {
viewBinding.scrollView.scrollToView(R.id.demo_view1)
}
//滚动到第二个View 上方偏移50像素
fun scrollView2Offset(view: View) {
viewBinding.scrollView.scrollToView(R.id.demo_view2,50)
}

现在已经可以滚动到指定的View位置了。接下来就是比较难的了。

锚点变化位置处理

现在只是能够滚动到指定的View了,但是这并不能完全满足业务需求。在UI上是要有一个Indicator指示器的,来指示当前已经滚动到哪个位置。

所以我们先增加一个集合,来保存滚动的锚点View。

val registerViews = mutableListOf()

并增加方法添加Views

fun addScrollView(vararg viewIds: Int) {
val views = Array(viewIds.size) { index ->
val view = findViewById(viewIds[index])
if (view == null) {
val missingId = rootView.resources.getResourceName(viewIds[index])
throw NoSuchElementException(“没有找到这个ViewId相关的View $missingId”)
}
view
}
registerViews.clear()
registerViews.addAll(views)
}

分析: 我们已经有了需要定位,需要监听变化的Views,当ScrollView滚动的时候,我们可以通过OnScrollChangeListener监听滚动,并获取注册的锚点View的位置改变信息。在onScrollChange中计算滚动偏移和滚动到哪个View。

在注册OnScrollChangeListener的时候我们也要保留外部的监听器使用。

init {
//调用父类的 不调用自身重写的
super.setOnScrollChangeListener(this)
}
//重写并保留外部的对象
override fun setOnScrollChangeListener(userListener: OnScrollChangeListener?) {
mUserListener = userListener
}

override fun onScrollChange(
v: NestedScrollView?,
scrollX: Int,
scrollY: Int,
oldScrollX: Int,
oldScrollY: Int
) {
//用户回调
mUserListener?.onScrollChange(v, scrollX, scrollY, oldScrollX, oldScrollY)
//计算逻辑
computeView()
}

我们接下来的所有操作都将会在computeView()这个方法中进行

我们先封装一个数据体用于保存Vie

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值