这篇文章不是我自己写的, 是 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.
*
* 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.
*/
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
的两种实现。下一篇我也会给出这两种方式的具体实现思路,敬请期待。