前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android ScrollView设置初始position的方法

Android ScrollView设置初始position的方法

作者头像
MelonTeam
发布2018-01-04 15:57:50
3.9K1
发布2018-01-04 15:57:50
举报

最近接了产品的一个需求,需要在一个拥有标题栏,内容区,图片区的滚动视图中,默认隐藏标题栏,而且支持用户手动下拉出现标题。

刚听到这个需求的时候,觉得这个很简单,直接设置ScrollView的初始滚动值即可。然而,当真正实现的时候却发现,Android压根没有方法可以设置ScrollView的初始滚动值。经过一系列的尝试,最终通过反射,修改成员变量的方法,实现了产品的需求。下面记录一下具体的踩坑过程。

这个就是需求的效果图。

这个是产品的要求,第一次进入的时候先展示标题,然后慢慢的向上滚动,最终隐藏。之后进入发表页都默认不展示标题栏,但是要支持用户可以下拉拉出标题栏。

动画的实现方案比较简单,进来之后等待一段时间,然后通过smoothScrollTo方法一点点的滚动ScrollView。然而,实验之后发现这个方法并不好用,没办法控制动画时间。后来改用Animator来实现,具体实现代码如下:

但是为难的是如何做到初始化ScrollView的默认滚动值。如果在onCreate里面调用scrollTo是无效的,因为这时候ScrollView都没有布局好。如果延时200ms之后再调用scrollTo,则用户会先看到标题然后再看到标题消失,体验不好。看起来似乎无解,难道一定要自己重载ScrollView来提供相关接口吗?

当我看着上面动画的代码发呆的时候,突然注意到了scrollY这个值,为什么Animator能够通过这个值来调整ScrollView的滚动位置呢?难道是通过反射scrollY这个成员变量动态修改它的value?

于是自己动手在onCreate的时候通过反射修改ScrollView的scollY属性。结果调试发现ScrollView压根没有这个属性。为什么呢?

查看了一下Animator的底层实现,发现scrollY并不是一个具体的属性成员

Animator建立了一个映射表,scrollY对应的PreHoneycombCompat.SCROLL_Y的具体值如下:

也就是说其实Animator是通过setScollY这个方法来实现动态滚动ScrollView的。而setScrollY的底层其实就是调用scrollTo。

到此似乎饶了个大圈子又回到了起点。前面已经尝试scrollTo在onCreate的时候就设置的话是无效的。

当我感到绝望的时候,看到了上图中的view.getScrollX(),既然有getScroolX那一定有getScrollY,既然有getScrollY那么一定有一个属性成员保存这个scrollY。一定!

通过断点和查看源码确认,这个保存ScrollView当前滚动位置的scrollY属性全名叫做mScrollY,而这个mScrollY并不是ScrollView的成员,而是其父类View的属性成员。

发现这个之后,将之前的反射代码直接修改成获取View的mScrollY变量,然后直接反射设置其初始高度。

编包后自测OK。

总结

一个小小的需求,暴露了自己对View的成员的不够了解,记录一下,提醒自己也方便大家。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-06-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档