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 条评论
登录 后参与评论

相关文章

来自专栏Android点滴积累

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

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

54870
来自专栏carven

利用canvas实现毛笔字帖(一)

最近在慕课网上找到了很好的canvas教程, 来自 @liuyubobobo 的 学写一个字 canvas绘图教程 在 @liuyubobobo 老师的系列ca...

21920
来自专栏较真的前端

关于事件的前端面试题总结

31350
来自专栏Python小屋

Python使用tkinter打造自定义对话框完整代码

问题来源:前一阵发过一个技术文章Python编写抽奖式随机提问程序,其中有个弹出式对话框,好像上海科技大学宋老师在群里当时问了一句对话框中中奖姓名是否能显示的大...

57640
来自专栏守候书阁

[边学边练]用简单实例学习React

学习之路不可停止,最近在玩 React。也动手尝试写了一个实例。借此整理总结下初步学习 React 的一些基础知识。因为这几天比较忙,没那么多时间,所以实例和文...

16060
来自专栏IMWeb前端团队

mouseenter与mouseover为何这般纠缠不清?

前言 项目地址 不知道大家在面试或者工作过程中有没有被mouseover和mouseenter(对应的是mouseout和mouseleave)事件所困扰。自...

29270
来自专栏数据小魔方

数据地图系列9|excel(VBA)数据地图!

今天要跟大家分享的是数据地图系列的第九篇——excel(VBA)数据地图! 关于VBA在excel中的应用非常广泛,本篇仅仅是给出示例代码,不会对基础操作做太过...

57760
来自专栏Java后端技术

jquery中dom元素的attr和prop方法的理解

  在编写使用高版本[ jQuery 1.6 开始新增了一个方法 prop()]的jquery插件进行编写js代码的时候,经常不知道dom元素的attr和pro...

9520
来自专栏我和未来有约会

DoubleAnimation方法

现在silverlight中还不支持直接用c#代码来创建动画,只能通过XamlReader来加载storyboard。 今天看了DoubleAnimation...

20970
来自专栏老司机的简书

老司机读书笔记——Weex学习笔记

Weex整体上与Vue语法大概一直,基本用法由阿里进行二次封装。以下主要介绍Weex的一些内置组件。

36640

扫码关注云+社区

领取腾讯云代金券