Android ScrollView设置初始position的方法

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

刚听到这个需求的时候,觉得这个很简单,直接设置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的成员的不够了解,记录一下,提醒自己也方便大家。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员的SOD蜜

获取SqlServer存储过程定义的3种方法

第一种: declare @p_text varchar(max) SELECT @p_text= text FROM syscomments WHERE...

2307
来自专栏用户2442861的专栏

mysql update,insert常用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/haluoluo211/article/d...

673
来自专栏Android点滴积累

Android ScrollView监听滑动到顶部和底部的两种方式(你可能不知道的细节)

Android ScrollView监听滑动到顶部和底部,虽然网上很多资料都有说,但是不全,而且有些细节没说清楚 使用场景: 1. 做一些复杂动画的时候,需要动...

2967
来自专栏JetpropelledSnake

SQL学习之MYSQL的常用命令和增删改查语句和数据类型

1486
来自专栏黑白安全

二次注入代码剖析

本文针对二次注入进行讲解,并简单的绕过360脚本waf。。。。。 首先来看程序的注册页面代码:

682
来自专栏机器学习算法与Python学习

SQL Server常用命令(平时不用别忘了)

SQL Server 2008 在Microsoft的数据平台上发布,可以组织管理任何数据。可以将结构化、半结构化和非结构化文档的数据直接存储到数据库中。可以对...

2757
来自专栏爱撒谎的男孩

Mybatis之ResultMap

3894
来自专栏Python小屋

Python+SQLite开发无界面版通信录管理系统

本文重点在于演示Python对SQLite数据库的操作,以及命令行式菜单的工作原理和实现。 首先使用SQLite Database Browser创建SQLit...

36213
来自专栏Python、Flask、Django

Flask 项目系列 -- 基于Flask打造招聘网站(2017-12-07更新)

1073
来自专栏维C果糖

史上最简单的 MySQL 教程(四十一)「触发器」

触发器:trigger,是指事先为某张表绑定一段代码,当表中的某些内容发生改变(增、删、改)的时候,系统会自动触发代码并执行。

41914

扫码关注云+社区