android 开机动画 渐变,[Parallax Animation]实现知乎 Android 客户端启动页视差滚动效果...

前言

Parallax Scrolling (视差滚动),是一种常见的动画效果。视差一词来源于天文学,但在日常生活中也有它的身影。在疾驰的动车上看风景时,会发现越是离得近的,相对运动速度越快,而远处的山川河流只是缓慢的移动着,这就是最常见的视差效果。视差动画独有的层次感能带来极为逼真的视觉体验,iOS、Android Launcher、Website 都将视差动画作为提升用户视觉愉悦度的不二选择。

客户端应用第一次打开出现引导页也不是什么新鲜的事儿,ViewPager 配上几张设计师精心绘制的图片,分分钟即可了事。但是总有人把平凡的事情做到不平凡,如本文的知乎客户端,亦或是新浪微博贺岁版,百度贴吧某版等众多应用里都出现了视差动画的身影,随着用户手指的滑动,反馈以灵动、贴近真实的视觉以及操作体验,对应用的初始印象登时被提升到一个极高的点。

给我印象最深的是去年新浪微博的贺岁版,引导页是一系列的年画,里面有红色剪纸的小孩儿,滑动界面的时候感觉这些元素在『动』,是真正的灵动,能勾起人童年的回忆,年味儿十足。不过话说我年怎么过跟新浪微博一毛钱关系都没有,但是这个启动页却是深得我意。只是这个版本的微博找不到了,正好前两天看到知乎的启动页做的也不错,就正好拿来练练手吧。

本文就知乎 Android 客户端启动页面为例,教你如何实现视差滚动效果。

2621820748c8508c0b8bd7e42773156c.gif

界面分析

细心把玩下知乎的启动页,不难分析出来,视差动画主要体现在背景层渐变、内容层元素差异滚动上,动画内容分别是:

- 内容:元素差异滚动,形成视差效果()

- 背景:随着界面的滑动,颜色由深蓝色渐变为浅蓝色()

- 文字:底部提示文案会随页面变动而切换,有简单的淡入淡出效果

- 界面动画:界面打开,元素的出场动画(第一页以及最后一页)

鉴于其它几项比较简单,本文主要讲视差动画以及背景渐变的实现,其它几项请自行参阅代码,见后文。

Parallax Scrolling

这里的视差滚动效果,主要表现为内容元素滚动速率的差异上。比如在 ViewPager 中滑动了 1px ,而 A 元素移动 2px , B 元素移动 1.5px ,这种移动差距的比率,我称之为 parallaxCofficient ,即 视差系数 或者 视差速率 ,正是同一个界面中的元素,由于层级不同,赋予的视差系数不同,在移动速度上的差异形成了视差的错觉,这就是我们要追求的效果。

那知道原理就好办了,使用 ViewPager.OnPageChangeListener ,动态计算不就得了。 no no no ! 后面完成背景渐变效果确实需要计算这个,但是 ViewPager 已经为我们准备好了变形元素 transformium : ViewPager.PageTransformer ,它有一个抽象方法 transformPage(View page, float position) ,正是为我们完成视差动画量身定制的。

ViewPager.PageTransformer

PageTransformer 在 ViewPager 滑动时被触发,它为我们自定义页面中进行视图变换打开了一扇大门。

javapublic abstract void transformPage (View page, float position)

在 ViewPager 源码中,我们可以很直观的看到它的调用过程:

java// ViewPager#onPageScrolled

if (mPageTransformer != null) {

final int scrollX = getScrollX();

final int childCount = getChildCount();

for (int i = 0; i < childCount; i++) {

final View child = getChildAt(i);

final LayoutParams lp = (LayoutParams) child.getLayoutParams();

if (lp.isDecor) continue;

final float transformPos = (float) (child.getLeft() - scrollX) / getClientWidth();

mPageTransformer.transformPage(child, transformPos);

}

}

Param 1: View page

从上面的代码中,不难看出,page 就是当前被滑动的页面,调试得知,每一个 child view 被 NoSaveStateFrameLayout 包装,也就是说 page.getChildAt(0) 即是每个 page 实际的 child view 。

Param 2: float position

position 这个参数不看代码或者文档,总会误以为就是我们熟知的 integer position ,不过它实际上是滑动页面的一个相对比例,本质跟 1、2、3、4 这种 position 是一样的。

比如知乎启动页共有 6 个页面,分别是 A、B、C、D、E、F 初始状态也就是 A 页面静止时,A 页面的 position 正好是 0 ,B 页面是 1 。而后滑动页面(B -> A),在这个过程中 A 的 position 是间于 [-1, 0] ,B 页面则是间于 [0, 1] 。

不过这个参数的文档却是简单不够直观,对照上面的例子,现在应该很清晰了。

Position of page relative to the current front-and-center position of the pager. 0 is front and center. 1 is one full page position to the right, and -1 is one page position to the left.

ParallaxTransformer

根据上面的分析,我们可以得出一个相对简单的自定义 transformer ,对 page view 进行遍历,递增或者递减其 parallaxCofficient ,以得到我们预期的效果,具体的系数设置请参考代码。

javaclass ParallaxTransformer implements ViewPager.PageTransformer {

float parallaxCoefficient;

float distanceCoefficient;

public ParallaxTransformer(float parallaxCoefficient, float distanceCoefficient) {

this.parallaxCoefficient = parallaxCoefficient;

this.distanceCoefficient = distanceCoefficient;

}

@Override

public void transformPage(View page, float position) {

float scrollXOffset = page.getWidth() * parallaxCoefficient;

// ...

// layer is the id collection of views in this page

for (int id : layer) {

View view = page.findViewById(id);

if (view != null) {

view.setTranslationX(scrollXOffset * position);

}

scrollXOffset *= distanceCoefficient;

}

}

}

背景渐变

留心才会发现,从第一页滑动到最后一页,背景色会平滑的从深蓝色过度到浅蓝色,这种效果又该怎么实现呢?

用过 Property Animation 的同学应该知道,以前的 Animation 只能用在 View 上,而 Property Animation 却可以用在任意类型属性值上,这归功于 TypeEvaluator 。

正好我们有 ArgbEvaluator ,它可以估算两个颜色值之间,任意部分的色值。因此,只需要指定起始色值以及最终的色值,传入滑动所对应的 fraction 即当前位置相对总距离的比例值,即可获得相应的色值。

javapublic class ArgbEvaluator implements TypeEvaluator {

public Object evaluate(float fraction, Object startValue, Object endValue) {

// ...

}

}

当然,前面说到需要使用 ViewPager.OnPageChangeListener 的:

javaclass GuidePageChangeListener implements ViewPager.OnPageChangeListener {

ArgbEvaluator mColorEvaluator;

int mPageWidth, mTotalScrollWidth;

int mGuideStartBackgroundColor, mGuideEndBackgroundColor;

public GuidePageChangeListener() {

mColorEvaluator = new ArgbEvaluator();

mPageWidth = getWindowManager().getDefaultDisplay().getWidth();

mTotalScrollWidth = mPageWidth * mAdapter.getCount();

mGuideStartBackgroundColor = getResources().getColor(R.color.guide_start_background);

mGuideEndBackgroundColor = getResources().getColor(R.color.guide_end_background);

}

@Override

public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

float ratio = (mPageWidth * position + positionOffsetPixels) / (float) mTotalScrollWidth;

Integer color = (Integer) mColorEvaluator.evaluate(ratio, mGuideStartBackgroundColor, mGuideEndBackgroundColor);

mPager.setBackgroundColor(color);

}

@Override

public void onPageSelected(int position) {}

@Override

public void onPageScrollStateChanged(int state) {}

}

源码

代码已经 push 到 Github 了,诸位自取。不过请注意,其素材均取自于知乎 Android 客户端(你懂的),学习交流即可,请勿用作商业用途。

还求更优雅的实现方式,欢迎发起 pull request 。

参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/533775.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js访问对方手机文件夹_求JS大神帮我写个利用JS来实现手机端和PC端访问自动选择样式文件代码...

展开全部现在比较流行的办法是 一个网站2套代码&#xff0c;一套是手机一套pc&#xff0c;在网站首页开e68a84e8a2ad3231313335323631343130323136353331333363353735头写上一段识别各浏览器的判断方法&#xff0c;根据结果引入不同的样式详细判断如下&#xff1a;var browser{…

python可以做计量分析吗_技术分享 - python数据分析(2)——数据特征分析(上)...

1 分布分析 分布分析能揭示数据的分布特征和分布类型。对于定量数据&#xff0c;欲了解其分布形式是对称的还是非对称的&#xff0c;发现某些特大或特小的可疑值&#xff0c;可通过绘制频率分布表、绘制频率分布直方图、绘制茎叶图进行直观地分析&#xff1b;对于定性分类数据&…

android lrc 歌词显示,Android歌词 AndroidLrc歌词

[ti:Android][ar:川畑要][al:0][by:黄病病][00:00.00][00:01.69]Android[00:07.51]歌手&#xff1a;川畑要[00:10.96]作詞&#xff1a;Kaname Kawabata[00:12.64]作曲&#xff1a;UTAKaname Kawabata[00:14.06]BY:黄病病[00:15.80][00:15.66]一際目を引くまるでandroid[00:23.1…

web前端开发技术期末考试_Web前端开发技术期末试题1

绝密★启用前Web前端开发技术期一、单项选择题(本大题共25小题&#xff0c;每小题1分&#xff0c;共25分)1.网页制作工具按照其工作方式可分为( )A.HTML语言和非HTML语言两大类B.DHTML方式和JavaScript方式两大类C.标注型网页制作工具和所见即所得型网页制作工具两大类D.基于Wi…

matlab的7.3版本是什么_乐建工程宝V6.3版本升级说明公告

尊敬的乐建工程宝客户&#xff1a;您好&#xff01;为了给客户提供更加优质的产品和服务&#xff0c;我司已于2019年11月20日开始乐建工程宝V6.3版本升级服务。目前&#xff0c;Android系统各应用市场已基本审核完毕&#xff0c;iOS系统已上传AppStore&#xff0c;目前苹果官方…

魅族android 版本 6.0下载,flyme6.0内测版

由魅族开发的全新安卓系统flyme6.0系统固件已经到来&#xff0c;相对于Flyme 5系统有了众多改变和提升&#xff0c;全新的智能服务系统&#xff0c;多达400于项全新功能&#xff0c;同时让操作界面更加简洁&#xff0c;易于操作&#xff0c;而系统运行速度也将有所提升&#xf…

origin设置不同区域的颜色_[测试狗]Origin入门教程(二十四):效率翻倍小技巧——修改默认字体...

在使用Origin的时候&#xff0c;对于每次绘图都需要更改字体觉得很麻烦&#xff0c;因为Origin默认的字体为Arial&#xff0c;但是我们常用的字体一般为Times New Roman&#xff0c;在下拉框的很底部&#xff0c;每次更改都很浪费时间。那为什么不把他设置成默认字体呢&#xf…

cgi web 调用多次启动_全面了解CGI、FastCGI、PHPFPM

一、抛个砖1、Web Server传递数据的方法正式说CGI之前&#xff0c;先来了解一下Web Server传递数据的另外一种方法&#xff1a;PHP Module加载方式。相信都会想起Apache吧&#xff0c;初学php时&#xff0c;在windows上安装完php和Apache之后&#xff0c;为了让Apache能够解析p…

android群英传神兵利器pdf,《Android群英传:神兵利器》勘误

1勘误一晃&#xff0c;我的新书《Android群英传:神兵利器》上市好多天了&#xff0c;有不少朋友已经拿到书了。本来以为&#xff0c;这次我看了不下十遍&#xff0c;再加上编辑们的校对&#xff0c;应该不会有很多勘误了吧~ 可事实证明&#xff0c;我还是太年轻啊&#xff01;大…

datatype未定义是什么意思_TypeError:无法读取未定义的属性'then'

loginService.islogged()上面的函数返回一个像“失败”的字符串 . 但是&#xff0c;当我尝试运行然后对它运行时&#xff0c;它将返回错误TypeError: Cannot read property then of undefined并且光标在 connected 之后和 .then 之前指示 .以下是完整功能&#xff1a;var conne…

python运行命令_对python中执行DOS命令的3种方法总结

1. 使用os.system("cmd") 特点是执行的时候程序会打出cmd在Linux上执行的信息。 import os os.system("ls") 2. 使用Popen模块产生新的process 现在大部分人都喜欢使用Popen。Popen方法不会打印出cmd在linux上执行的信息。的确&#xff0c;Popen非常强大&a…

android studio 不生成buildconfig,Android Studio Update 0.4.0找不到buildConfig()

将Android Studio升级到版本0.4.0后&#xff0c;出现了一个新错误&#xff1a;我通过gradle-wrapper.properties升级到gradle 1.9distributionUrlhttp\://services.gradle.org/distributions/gradle-1.9-all.zip并升级了build.gradle中的gradle版本dependencies {classpath com…

谭民机器人_机器人视觉伺服研究进展-中科院自动化所-谭民.

文章编号:100220446(2004 0320277206机器人视觉伺服研究进展Ξ王麟琨,徐德,谭民(中国科学院自动化研究所复杂系统与智能科学实验室,北京100080摘要:,针对当前机器人视觉伺服所面临的主要问题, .关键词:机器人;视觉伺服;综述中图分类号::Survey of R esearch on Robotic Visual …

mysql 按月和年累加_广西柳州市市场监管局公布市2020年11月(第一批)电梯按需维保试点名单...

中国质量新闻网讯 根据《柳州市改进电梯维护保养模式试点工作方案》&#xff0c;近日&#xff0c;广西柳州市市场监管局公布柳州市首批按需维保试点电梯名单&#xff0c;冠亚蓝湾国际小区和南庆安置小区共46台电梯成为首批试点电梯&#xff0c;标志着柳州市全面启动了按需维保改…

python默认深拷贝_Python 深拷贝与浅拷贝

首先分享Python里面的数据类型1、不可变类型&#xff1a;Number(数字)、String(字符串)、Tuple(元组)。不可变数据类型在第一次声明赋值的时候, 会在内存中开辟一块空间, 用来存放这个变量被赋的值, 而这个变量实际上存储的, 并不是被赋予的这个值, 而是存放这个值所在空间的内…

上传 mp4 格式判断_视频如何转换成通用的MP4格式?按下这个键,10秒就能搞定...

我们在网上下载视频的时候&#xff0c;有很多的视频都是无法播放的&#xff0c;或者是需要特定的播放器才可以播放。其实&#xff0c;只要把这些视频的格式转换成通用的MP4格式即可。如果你还不知道怎么转换视频格式&#xff0c;下面就教大家两个小方法&#xff0c;百试百灵。一…

android不能在主线程,安卓开发:主线程真的不能做UI操作吗?这一点很多程序员都没想到...

只要参与过安卓项目开发一两年的朋友们应该清楚&#xff0c;为了避免UI渲染出现异常安卓框架限制UI操作只能在主线程中进行&#xff0c;如果贸然在子线程做了UI操作结果会怎样&#xff1f;我们随便写下了如下测试代码。不出意外的话&#xff0c;代码执行报错抛出了名为CalledFr…

c++注释快捷键_Jupyter Notebook amp; Lab快捷键大全

Jupyter有两种模式&#xff0c;命令模式和编辑模式&#xff0c;分别有不同的快捷键。编辑模式(按键 Enter 切换)&#xff1a;可以往单元中键入代码或文本&#xff0c;此时单元格被蓝色的框线包围&#xff0c;且命令模式下的快捷键不生效&#xff1b; 命令模式 (按键 Esc 开启)&…

多核cpu应用场景_CPU占用100%!PC卡顿原来可以这么解决:多场景多任务也流畅

现代生活里&#xff0c;不论是工作还是生活&#xff0c;多开软件和处理事务可以说都是家常便饭的事情。一边玩着醉心已久的游戏&#xff0c;一边解压着新的电影和游戏&#xff1b;为了查询资料&#xff0c;一不小心打开了数十个网页&#xff1b;复杂繁重的工作铸就了动辄上百兆…

swot分析法案例_项目型销售案例剖析的五大步骤

我们的案例分析方式是根据哈佛大学与中欧国际工商学院的案例分析方法来总结出我们的模式的。这种分析方法包括两种互相关联和依赖的方面。第一方面&#xff0c;就是要对所指定的将供集体讨论的案例&#xff0c;做出深刻而有意义的分析&#xff0c;包括找出案例所描述的情景中存…