這篇文章不是我自己寫的, 是 Stew 寫的,我發在我的簡書,為了公眾賬號可以有一個原文鏈接,因為公眾賬號比較看代碼不方便。
應部門大神邀請,寫一篇關于 Android 動畫方面的小記,也算是一種鍛煉吧,自知菜鳥,學識淺陋,有錯提之。
?ViewPager 是谷歌官方給我們提供的一個向下兼容包(Android-support-v4.jar)里面的一個類。我可以用其做簡單的app引導頁,也可以做一些復雜的頁菜單(類似網易新聞,簡書等app的頁面菜單)。不熟悉 ViewPager 的同學可以參照如下鏈接進行學習:
- http://blog.csdn.net/harvic880925/article/details/38453725 (harvic 大神寫的基礎篇)
- http://developer.android.com/reference/android/support/v4/view/ViewPager.html ViewPager 對應官方文檔地址
具體細節不再敖述,下面我們直接進入主題—— Viewpager 切換動畫
ViewPager
是從 Android 3.0 開始支持自定義動畫的,官方給出了 PageTransformer 接口和其唯一的方法 transformPage(View view, float position) ,所以只要實現該接口就可以了。
/**
* A PageTransformer is invoked whenever a visible/attached page is scrolled.
* This offers an opportunity for the application to apply a custom transformation
* to the page views using animation properties.
*
* <p>As property animation is only supported as of Android 3.0 and forward,
* setting a PageTransformer on a ViewPager on earlier platform versions will
* be ignored.</p>
*/
public interface PageTransformer {
/**
* Apply a property transformation to the given page.
*
* @param page Apply the transformation to this page
* @param position 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.
*/
public void transformPage(View page, float position);
}
從官方文檔可以看出,在 transformPage
方法中, 會傳遞兩個參數, page
即當前界面,以及該 page
對應的 position
。重點在于參數 position
,其意思是當前界面的位置相對于屏幕中心的偏移量。在滑動界面時,參數 position
是實時變化的,具體規律如下:
- 開始或活動結束:
當position = 0 :當前界面位于屏幕中心
當position = 1 :當前Page剛好滑出屏幕,位于屏幕右側
當position = -1 :當前Page剛好滑出屏幕,位于屏幕左側
- 滑動過程中:
滑動過程中涉及到兩個 page ,當前 page 和下一個
page
(一個滑出屏幕,一個滑入屏幕),且都會執行transformPage
方法。舉個簡單例子:從前往后有 A、B、C 3個界面的引導頁,開始顯示 A 界面,然后手指向左滑動,A 界面開始向左滑出屏幕,B 界面開始向左滑入屏幕,A 界面的position
從0
漸變到-1
,B 界面的position
從 1 漸變到 0 。
可以想象到兩者的 position 的絕對值相加一直是1。同學們可以將 position 用日志打出來觀察其具體的變化規律。掌握了position的變化規律,就不難理解,為什么可以將 position 運用到我們的切換動畫中了。我們可以對 page 本身設置 setAlpha()
, setTranslationX()
, setTranslationY()
, setScaleX()
, setScaleY()
方法,也可以對 page 中的內容設置動畫,前提是通過 page
找到 page
中的內容。
下面舉一個 我自己做的 Demo ( page 有動畫,page 中的內容也有動畫)
效果如下:
核心代碼如下:
@Override
public void transformPage(View page, float position) {
RelativeLayout backgroundView = (RelativeLayout) page.findViewById(R.id.simple_pager_bg);
View text_head = page.findViewById(R.id.slide_fragment_text_1);
View text_content = page.findViewById(R.id.slide_fragment_text_2);
View welcomeImage01 = page.findViewById(R.id.slide_pic_1);
View welcomeImage02 = page.findViewById(R.id.slide_pic_2);
View welcomeImage03 = page.findViewById(R.id.slide_pic_3);
View welcomeImage04 = page.findViewById(R.id.slide_pic_4);
if (0 <= position && position < 1) {
ViewHelper.setTranslationX(page, pageWidth * -position);
}
if (-1 < position && position < 0) {
ViewHelper.setTranslationX(page, pageWidth * -position);
}
if (position <= -1.0f || position >= 1.0f) {
//當前界面已經向左或者向右滑出屏幕
}
else if (position == 0.0f) {
//當前界面未滑動或者滑動結束
}
else {
//滑動過程中
if (backgroundView != null) {
ViewHelper.setAlpha(backgroundView, 1.0f - Math.abs(position));
}
if (text_head != null) {
ViewHelper.setTranslationX(text_head, pageWidth * position);
ViewHelper.setAlpha(text_head, 1.0f - Math.abs(position));
}
if (text_content != null) {
ViewHelper.setTranslationX(text_content, pageWidth * position);
ViewHelper.setAlpha(text_content, 1.0f - Math.abs(position));
}
if (welcomeImage01 != null) {
ViewHelper.setRotationY(welcomeImage01, 90 * position);
ViewHelper.setAlpha(welcomeImage01, 1.0f - Math.abs(position));
}
if (welcomeImage02 != null) {
ViewHelper.setRotationY(welcomeImage02, 90 * position);
ViewHelper.setAlpha(welcomeImage02, 1.0f - Math.abs(position));
}
if (welcomeImage03 != null) {
ViewHelper.setRotationY(welcomeImage03, 90 * position);
ViewHelper.setAlpha(welcomeImage03, 1.0f - Math.abs(position));
}
if (welcomeImage04 != null) {
ViewHelper.setRotationY(welcomeImage04, 90 * position);
ViewHelper.setAlpha(welcomeImage04, 1.0f - Math.abs(position));
}
}
}
Github上類似的效果有很多
https://github.com/daimajia/AndroidImageSlider(代碼家寫的動畫庫,強烈推薦!)
https://github.com/prolificinteractive/ParallaxPager
https://github.com/flavienlaurent/discrollview
https://github.com/andraskindler/parallaxviewpager
主要是以前沒研究過 PageTransformer
,其實實現起來很簡單,但是功能很強大,如果能善于運用position參數,可以做出非常炫酷的效果。
其實對于上述 Viewpager
的 page
切換動畫可以有2種方式(只考慮 page
),不僅可以用 transformPage
方式,也可以用 onPageScrolled
方式。具體細節可以參照 AndroidImageSlider
和 JazzyViewPager
的兩種實現。下一篇我也會給出這兩種方式的具體實現思路,敬請期待。
其實對于上述 Viewpager
的 page
切換動畫可以有2種方式(只考慮 page
),不僅可以用 transformPage
方式,也可以用 onPageScrolled
方式。具體細節可以參照 AndroidImageSlider
和 JazzyViewPager
的兩種實現。下一篇我也會給出這兩種方式的具體實現思路,敬請期待。