【Parallax Animation】實現知乎 Android 客戶端啟動頁視差滾動效果
前言
Parallax Scrolling(視差滾動)
,是一種常見的動畫效果。視差一詞來源於天文學,但在日常生活中也有它的身影。在疾馳的動車上看風景時,會發現越是離得近的,相對運動速度越快,而遠處的山川河流只是緩慢的移動著,這就是最常見的視差效果。視差動畫獨有的層次感能帶來極為逼真的視覺體驗,iOS、Android
Launcher、Website都將視差動畫作為提升使用者視覺愉悅度的不二選擇。
客戶端應用第一次打開出現引導頁也不是什麼新鮮的事兒,ViewPager
配上幾張設計師精心繪製的圖片,分分鐘即可了事。但是總有人把平凡的事情做到不平凡,如本文的知乎客戶端,亦或是新浪微博賀歲版,百度貼吧某版等眾多應用裡都出現了視差動畫的身影,隨著使用者手指的滑動,反饋以靈動、貼近真實的視覺以及操作體驗,對應用的初始印象登時被提升到一個極高的點。
給我印象最深的是去年新浪微博的賀歲版,引導頁是一系列的年畫,裡面有紅色剪紙的小孩兒,滑動介面的時候感覺這些元素在『動』,是真正的靈動,能勾起人童年的回憶,年味兒十足。不過話說我年怎麼過跟新浪微博一毛錢關係都沒有,但是這個啟動頁卻是深得我意。只是這個版本的微博找不到了,正好前兩天看到知乎的啟動頁做的也不錯,就正好拿來練練手吧。
本文就知乎Android客戶端啟動頁面為例,教你如何實現視差滾動效果。
介面分析
細心把玩下知乎的啟動頁,不難分析出來,視差動畫主要體現在背景層漸變、內容層元素差異滾動上,動畫內容分別是:
- 內容:元素差異滾動,形成視差效果(*)
- 背景:隨著介面的滑動,顏色由深藍色漸變為淺藍色(*)
- 文字:底部提示文案會隨頁面變動而切換,有簡單的淡入淡出效果
- 介面動畫:介面開啟,元素的出場動畫(第一頁以及最後一頁)
鑑於其它幾項比較簡單,本文主要講視差動畫以及背景漸變的實現,其它幾項請自行參閱程式碼,見後文。
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
滑動時被觸發,它為我們自定義頁面中進行檢視變換打開了一扇大門。
public abstract void transformPage (View page, float position)
在ViewPager
原始碼中,我們可以很直觀的看到它的呼叫過程:
// 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
,以得到我們預期的效果,具體的係數設定請參考程式碼。
class 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
即當前位置相對總距離的比例值,即可獲得相應的色值。
public class ArgbEvaluator implements TypeEvaluator {
public Object evaluate(float fraction, Object startValue, Object endValue) {
// ...
}
}
當然,前面說到需要使用ViewPager.OnPageChangeListener
的:
class 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
。
參考
相關推薦
【Parallax Animation】實現知乎 Android 客戶端啟動頁視差滾動效果
前言 Parallax Scrolling(視差滾動),是一種常見的動畫效果。視差一詞來源於天文學,但在日常生活中也有它的身影。在疾馳的動車上看風景時,會發現越是離得近的,相對運動速度越快,而遠處的山川河流只是緩慢的移動著,這就是最常見的視差效果。視差動畫獨有的層次感能
知乎 Android 客戶端元件化實踐
背景 知乎 Android 客戶端最早使用的是最常見的單工程 MVC 架構,所有業務邏輯都放在了主工程 Module 裡,網路層和一些公共程式碼分別被抽成了一個 Module。現在看來,當時的業務線、產品功能及研發團隊都比不上現在的體量和豐富度,遇到的問題隨時組內溝通就可以解決。所以在知乎穩步發
Android SwipeRefreshLayout官方下拉重新整理控制元件介紹(與知乎Android客戶端下拉重新整理一樣!!)
轉載出處:http://blog.csdn.net/lmj623565791/article/details/24521483 //沒少看鴻洋老師的視訊,一如既往,鴻洋老師講解的淺顯易懂! 下面App基本都有下拉重新整理的功能,以前基本都使用XListView或者自己
知乎日報客戶端--知乎日報板塊的實現
看完這一篇你應該學會:如何展示新聞資訊類,效果圖: 這一篇的知識點: Fragment的替換,Recylerview[adapter, holder]的使用,Okhttp,JSONObject解析json 還是先給佈局: zhihufragment.xml Recyl
【WCF系列】(四)WCF客戶端怎麽消費服務
class fig 完全 文件 自動 客戶 回收 ins 必須 WCF客戶端怎麽消費服務 獲取服務綁定協議、綁定和地址:實現方式 SvcUtil方式:SvcUtil.exe是一個命令行工具,位於:C:\Program Files (x86)\Microsoft SDKs
實現PHP伺服器+Android客戶端(Retrofit+RxJava)第一天基礎搭建
前段不知道怎麼的android寫著寫著有些寫不動了,於是開始搗鼓php,想要自己寫個網站什麼的裝裝逼,於是最近android就有些荒廢了,說要解析fresco的也放了很久,之前在github上提問,昨天突然收到了facebook工程師的回信,又記起來這件事情,本
實現PHP伺服器+Android客戶端(Retrofit+RxJava)第四天客戶端與伺服器通訊的實現
我的上一篇文章已經介紹了retrofit+rxjava的配置(包括快取),從這一篇開始就開始講我要實現的這個app網路請求部分的構思,也就是要請求那些資料,資料的型別等等。 我要實現的客戶端 看圖: 看了介面基本應該能知道要實現的效果了
實現PHP伺服器+Android客戶端(Retrofit+RxJava)第五天學一學ndk開發吧
前兩天發現一本相當可以的書Java 效能權威指南,粗略的看了兩天,對於我這種還在去中級的路上的人,看著的確是挺累的,所以也就歇了幾天沒有寫部落格了。看了那麼高深的東西還是要繼續回來鞏固一下實戰水平,所以今天繼續來講我的這個應用的實現過程,在上篇文章實現PHP伺服
實現PHP伺服器+Android客戶端(Retrofit+RxJava)第三天Retrofit的配置以及快取的實現
上一篇講了介面,這篇文章就要講客戶端網路請求部分的內容了,主要用到的就是Retrofit+RxJava,其實準確來說是Retrofit+RxJava+OkHttp, 最新的Retrofit是2.0.2版本,原始碼地址:retrofit 學習retrofit:
實現PHP伺服器+Android客戶端(Retrofit+RxJava)第六天推送的實現
廢話不多說,今天來說說近幾天的成果。 如何實現推送 android客戶端nio的使用 為啥要使用長連線 長連線的建立 php伺服器如何實現長連線 後期需要優化的部分 如何實現推送 推送的原理其實也很簡單,伺服器和客戶端實現長連線,實現了長連線之後就
實現PHP伺服器+Android客戶端(Retrofit+RxJava)第二天客戶端介面的大致實現
本篇文章講的是客戶端的部分,也會丟擲一些伺服器端實現的想法。 上一篇文章:PHP伺服器+Android客戶端(Retrofit+RxJava)實踐第一天 連通了PHP伺服器和Android客戶端,客戶端請求,伺服器響應之後在客戶端列印了hello world,
python搭建伺服器實現兩個Android客戶端間收發訊息
python伺服器 # coding:utf-8 import socket import threading import time def handle_client(client_socket, client_id): """處理客戶端請求
支付寶客戶端架構解析:Android 客戶端啟動速度優化之「垃圾回收」
前言 《支付寶客戶端架構解析》系列將從支付寶客戶端的架構設計方案入手,細分拆解客戶端在“容器化框架設計”、“網路優化”、“效能啟動優化”、“自動化日誌收集”、“RPC 元件設計”、“移動應用監控、診斷、定位”等具體實現,帶領大家進一步瞭解支付寶在客戶端架構上的迭代與優化歷程。 本節將介紹支付寶 Andro
愛奇藝Android客戶端啟動優化與分析
1 簡介 網際網路領域裡有個八秒定律,如果網頁開啟時間超過8秒,便會有超過70%的使用者放棄等待,對Android APP而言,要求更加嚴格,如果系統無響應時間超過5秒,便會出現ANR,APP可能會被強制關閉,因此,啟動時間作為一個重要的效能指標,關係著使用者的第一體驗。 愛奇藝安卓APP非
愛奇藝技術分享:愛奇藝Android客戶端啟動速度優化實踐總結
本文由愛奇藝技術團隊原創分享,原題《愛奇藝Android客戶端啟動優化與分析》。 1、引言 網際網路領域裡有個八秒定律,如果網頁開啟時間超過8秒,便會有超過70%的使用者放棄等待,對Android APP而言,要求更加嚴格,如果系統無響應時間超過5秒,便會出現ANR,APP可能會被強制關閉,
【Android】仿知乎夜間模式的實現
1.簡介 目前很多App都有夜間模式的功能,網上教程也是很多,最近專案不忙,抽空學習了下,在這做下記錄,希望能幫到正在看部落格的你,我們先來看下知乎的效果: 看我的效果: 臥槽,好像啊,哈
【專案原始碼】- 【模仿知乎日報】模仿知乎日報
這個本人目前做的最好的一個模仿品,僅供學習使用,當然裡面也是有很多問題,做的時間不多,將近一個禮拜。(Eclipse製作) 先貼上效果圖: 效果圖上完了,說下涉及的知識點吧: 1、先是進入時的歡迎介面的動畫Animation、網路的判斷 2、viewpager自動動畫
【iOS】仿知乎日報,RxSwift-Part2-詳情頁的搭建
前言 在上一篇,我們搭建了首頁。而這篇,我們將開始搭建話題詳情頁。 分析 還是先來看下演示gif { "body": "<div class=\"main-wrap content-wrap\">\n<div cla
【視頻】零基礎學Android開發:藍牙聊天室APP(一)
android入門 mod http 開發 org 薪資 get target 下載 零基礎學Android開發:藍牙聊天室APP第一講 1. Android介紹與環境搭建:史上最高效Android入門學習 1.1 Google的大小戰略 1.2 物聯網與雲計算 1.3
【樹莓派】樹莓派刷Android系統
net 文章 圖文 str 鍵盤操作 左右移動 ima 工具 解決 樹莓派3安裝Android TV系統圖文教程 http://www.mz6.net/news/android/6866.html 樹莓派3 Android TV系統怎樣安裝?樹莓派3一個重要用途就是當智