【Android Developers Training】 70. 使用ViewPager实现屏幕滑动
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好。
原文链接:http://developer.android.com/training/animation/screen-slide.html
屏幕滑动是从一个完整的屏幕转换到另一个屏幕的动画,对于配置向导或者幻灯片的应用场景是很常见的。这节课将会展示如何使用support library.ViewPager提供的
ViewPager来自动实现滑动的动画。下面是一个屏幕滑动的动画例子:
如果你希望略过这部分内容直接看代码样例,可以直接下载样例代码,然后选择淡入淡出动画的例子。下面的文件是实现代码:
src/ScreenSlidePageFragment.java
src/ScreenSlideActivity.java
layout/activity_screen_slide.xml
layout/fragment_screen_slide_page.xml
一). 创建视图
创建一个布局文件,你马上就会使用到它作为一个fragment的内容布局。下面的代码是一个例子,包含了一个文本框显示一些文本:
- <!-- fragment_screen_slide_page.xml -->
- <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/content"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
- <TextView style="?android:textAppearanceMedium"
- android:padding="16dp"
- android:lineSpacingMultiplier="1.2"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/lorem_ipsum" />
- </ScrollView>
同时记得给这个fragment定义一个字符串。
二). 创建一个Fragment
创建一个Fragment类,在onCreateView()中返回你刚才创建的布局。当你需要向用户显示新的一页时,你可以之后在父activity中创建这个fragment的实例:
- import android.support.v4.app.Fragment;
- ...
- public class ScreenSlidePageFragment extends Fragment {
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- ViewGroup rootView = (ViewGroup) inflater.inflate(
- R.layout.fragment_screen_slide_page, container, false);
- return rootView;
- }
- }
三). 添加一个ViewPager
ViewPager拥有内置的页面间滑动手势并且默认是显示滑动动画的,所以你不需要创建任何动画。 ViewPager使用PagerAdapter作为一个要显示的新页面的提供者,所以PagerAdapter会使用你之前创建的fragment类。
首先,创建一个包含ViewPager的布局:
- <!-- activity_screen_slide.xml -->
- <android.support.v4.view.ViewPager
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/pager"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
创建一个activity,它完成下列事情:
- 将视图的布局设置为包含了ViewPager的布局。
- 创建一个继承FragmentStatePagerAdapter抽象类的类,并且实现getItem()方法来提供ScreenSlidePageFragment的实例作为新的页面。这个页面适配器(Pager Adapter)还要求你实现getCount()方法,它返回适配器需要创建的页面数量(比如说有五页)。
- 将PagerAdapter与ViewPager关联起来。
- 处理设备的后退按键,让它实现在虚拟堆栈中向后移动。如果用户已经在第一页了,回到activity的后退堆栈。
- import android.support.v4.app.Fragment;
- import android.support.v4.app.FragmentManager;
- ...
- public class ScreenSlidePagerActivity extends FragmentActivity {
- /**
- * The number of pages (wizard steps) to show in this demo.
- */
- private static final int NUM_PAGES = 5;
- /**
- * The pager widget, which handles animation and allows swiping horizontally to access previous
- * and next wizard steps.
- */
- private ViewPager mPager;
- /**
- * The pager adapter, which provides the pages to the view pager widget.
- */
- private PagerAdapter mPagerAdapter;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_screen_slide);
- // Instantiate a ViewPager and a PagerAdapter.
- mPager = (ViewPager) findViewById(R.id.pager);
- mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
- mPager.setAdapter(mPagerAdapter);
- }
- @Override
- public void onBackPressed() {
- if (mPager.getCurrentItem() == 0) {
- // If the user is currently looking at the first step, allow the system to handle the
- // Back button. This calls finish() on this activity and pops the back stack.
- super.onBackPressed();
- } else {
- // Otherwise, select the previous step.
- mPager.setCurrentItem(mPager.getCurrentItem() - 1);
- }
- }
- /**
- * A simple pager adapter that represents 5 ScreenSlidePageFragment objects, in
- * sequence.
- */
- private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
- public ScreenSlidePagerAdapter(FragmentManager fm) {
- super(fm);
- }
- @Override
- public Fragment getItem(int position) {
- return new ScreenSlidePageFragment();
- }
- @Override
- public int getCount() {
- return NUM_PAGES;
- }
- }
- }
二). 通过PageTransformer自定义动画
要显示一个与默认的滑动屏幕动画不同的动画,需要实现ViewPager.PageTransformer接口,并将它提供给ViewPager。该接口有一个共有方法:transformPage()。每次屏幕切换,该方法都会为每一个可见的页面(一般来说都只有一个可见页面)及相邻的离开屏幕范围的页面执行一次。例如,如果当前第三页是可见的,并且用户滑动到了第四页,那么transformPage()方法会在手势执行的过程中,分别为第二页,第三页和第四页进行调用。
在你的transformPage()的实现中,你可以根据当前屏幕所显示的页的位置,确定哪些页需要变化,创建自定义的滑动动画,着可以通过transformPage()方法的position参数获得。
position变量指出了某个页面相对于中心的位置。这个变量会随着用户在页面间切换而动态变化。当一个页面充满屏幕时,它的position值是0。当一个页面被拉出到了屏幕右侧,它的position值是1。如果用户在页面一和页面二切换过程中,那么页面一的position值为-0.5,页面二的position值为0.5。根据页面对于屏幕的位置,你可以通过设置页面的属性,比如:setAlpha(),setTranslationX()或setScaleY(),来创建自定义的滑动动画。
当你有一个PageTransformer的实现,在你的实现中调用setPageTransformer()来应用你的自定义动画。例如,如果你有一个叫ZoomOutPageTransformer的PageTransformer,你可以这样设置你的自定义动画:
- ViewPager mPager = (ViewPager) findViewById(R.id.pager);
- ...
- mPager.setPageTransformer(true, new ZoomOutPageTransformer());
拉远页面切换(Zoom-out)
这个动画会缩小页面然后在滑动过程中淡化相邻的页面。在一个页面接近中心的时候,它会回到它的标准大小并且淡入。
- public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
- private static final float MIN_SCALE = 0.85f;
- private static final float MIN_ALPHA = 0.5f;
- public void transformPage(View view, float position) {
- int pageWidth = view.getWidth();
- int pageHeight = view.getHeight();
- if (position < -1) { // [-Infinity,-1)
- // This page is way off-screen to the left.
- view.setAlpha(0);
- } else if (position <= 1) { // [-1,1]
- // Modify the default slide transition to shrink the page as well
- float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
- float vertMargin = pageHeight * (1 - scaleFactor) / 2;
- float horzMargin = pageWidth * (1 - scaleFactor) / 2;
- if (position < 0) {
- view.setTranslationX(horzMargin - vertMargin / 2);
- } else {
- view.setTranslationX(-horzMargin + vertMargin / 2);
- }
- // Scale the page down (between MIN_SCALE and 1)
- view.setScaleX(scaleFactor);
- view.setScaleY(scaleFactor);
- // Fade the page relative to its size.
- view.setAlpha(MIN_ALPHA +
- (scaleFactor - MIN_SCALE) /
- (1 - MIN_SCALE) * (1 - MIN_ALPHA));
- } else { // (1,+Infinity]
- // This page is way off-screen to the right.
- view.setAlpha(0);
- }
- }
- }
深度页面动画(Depth)
这个动画对于向左滑动的页面使用默认的滑动动画,而对于从右侧滑入的页面使用深度动画。该动画淡出页面,并且线性地缩小它的大小。
Note:
在深度动画过程中,默认的动画(屏幕滑动)仍然发生,所以你必须用一个负X方向来抵消屏幕滑动,例如
- view.setTranslationX(-1 * view.getWidth() * position);
下面的例子展示了如何在一个工作页面中,抵消默认的屏幕滑动动画:
- public class DepthPageTransformer implements ViewPager.PageTransformer {
- private static final float MIN_SCALE = 0.75f;
- public void transformPage(View view, float position) {
- int pageWidth = view.getWidth();
- if (position < -1) { // [-Infinity,-1)
- // This page is way off-screen to the left.
- view.setAlpha(0);
- } else if (position <= 0) { // [-1,0]
- // Use the default slide transition when moving to the left page
- view.setAlpha(1);
- view.setTranslationX(0);
- view.setScaleX(1);
- view.setScaleY(1);
- } else if (position <= 1) { // (0,1]
- // Fade the page out.
- view.setAlpha(1 - position);
- // Counteract the default slide transition
- view.setTranslationX(pageWidth * -position);
- // Scale the page down (between MIN_SCALE and 1)
- float scaleFactor = MIN_SCALE
- + (1 - MIN_SCALE) * (1 - Math.abs(position));
- view.setScaleX(scaleFactor);
- view.setScaleY(scaleFactor);
- } else { // (1,+Infinity]
- // This page is way off-screen to the right.
- view.setAlpha(0);
- }
- }
- }
【Android Developers Training】 70. 使用ViewPager实现屏幕滑动的更多相关文章
- 【Android Developers Training】 12. 支持不同屏幕
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- 【Android Developers Training】 68. 序言:添加动画
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- 【Android Developers Training】 10. 序言:支持不同设备
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- 【Android Developers Training】 60. 在你的UI中显示位图
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- 【Android Developers Training】 58. 缓存位图
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- 【Android Developers Training】 55. 序言:高效显示位图
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- 【Android Developers Training】 9. 覆盖于布局之上的Action Bar
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- 【Android Developers Training】 7. 添加Action Buttons
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- 【Android Developers Training】 4. 启动另一个Activity
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
随机推荐
- 简单的记录,VMware Tools的安装
VMware Tools是VMware虚拟机中自带的一种增强工具,只有在VMware虚拟机中安装好了VMware Tools,才能实现主机与虚拟机之间的文件共享,同时可支持自由“拖拽”的功能来对传文件 ...
- 全景智慧城市——NOW!!!VRSHOPPING颠覆你的购物认知!
互联网+时代,人们对现有的网络资源已经不再感冒,一般的图片.文字信息已经无法满足人们对互联网的需求,虚拟现实.身临其境的体验是不可小觑的发展趋势,尤其是VR逛街.购物,更会深入人心,再次改变人们的生活 ...
- asp.net Socket的简单Web Server
1.首先初始化socket,包含对端点以及对连接队列长度的初始化 IPAddress address = IPAddress.Loopback; IPEndPoint endPoint = ); So ...
- 深入理解Struts2----类型转换
之前的一系列文章主要介绍了有关Struts2的一些基本用法和部分的简单原理,但是始终没有介绍有关拦截器的相关内容,从本篇开始我们将从另一个角度去深入理解框架的使用,核心还是拦截器,但本篇首先 ...
- 写给Android App开发人员看的Android底层知识(1)
这个系列的文章一共8篇,我酝酿了很多年,参考了很多资源,查看了很多源码,直到今天把它写出来,也是战战兢兢,生怕什么地方写错了,贻笑大方. (一)引言 早在我还是Android菜鸟的时候,有很多技术我都 ...
- 数据结构与算法系列研究七——图、prim算法、dijkstra算法
图.prim算法.dijkstra算法 1. 图的定义 图(Graph)可以简单表示为G=<V, E>,其中V称为顶点(vertex)集合,E称为边(edge)集合.图论中的图(graph ...
- 微信小程序demo
微信小程序demo github地址 去年小程序刚发布时特别火,赶潮流做了个demo.感觉小程序开发还是比较简单的,主要是官方文档写得比较好,遗憾的是很多API需要微信认证才能使用. 由于小程序包大小 ...
- Java基础知识二次学习--第五章 数组
第五章 数组 时间:2017年4月26日15:11:30~2017年4月26日15:15:54 章节:05章_01节 视频长度:09:30 内容:一维数组的内存分析 心得: Java中数组是引用类型 ...
- Selenium 高阶应用之WebDriverWait 和 expected_conditions
Seleniium 是相当不错的一个第三方测试框架,可惜目前国内已经无法访问其官网(FQ可以). 不知道大家是否有认真查看过selenium 的api,我是有认真学习过的.selenium 的api中 ...
- aws上redhat安装lmysql服务记
aws上redhat安装lmysql服务记 1.准备材料 1.1