<Android 基础(十七)> ViewPager
2016-07-09 08:53
453 查看
介绍
Layout manager that allows the user to flip left and rightthrough pages of data. You supply an implementation of a
{@link PagerAdapter} to generate the pages that the view shows.
ViewPager is most often used in conjunction with {@link android.app.Fragment},
which is a convenient way to supply and manage the lifecycle of each page.
There are standard adapters implemented for using fragments with the ViewPager,
which cover the most common use cases. These are
{@link android.support.v4.app.FragmentPagerAdapter} and
{@link android.support.v4.app.FragmentStatePagerAdapter}; each of these
classes have simple code showing how to build a full user interface
with them.
Views which are annotated with the {@link DecorView} annotation are treated as
part of the view pagers ‘decor’. Each decor view’s position can be controlled via
its {@code android:layout_gravity} attribute. For example:
<android.support.v4.view.ViewPager android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v4.view.PagerTitleStrip android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="top" /> </android.support.v4.view.ViewPager>
翻译:
ViewPager允许用户通过载有数据的页面实现左右滑动。开发者需要自己实现PagerAdapter来生成需要显示的页面。
ViewPager通常回合Fragment结合起来使用,这样实现起来比较简单同时也便于管理每个页面的生命周期。Android存在标准的适配器模板针对Fragment和ViewPager结合使用的方式:
android.support.v4.app.FragmentPagerAdapter
android.support.v4.app.FragmentStatePagerAdapter
每个类都有简单的说明,告诉开发者如何通过他们来实现与用户的交互。
被注释成DecorView的视图均可当做ViewPager的一部分,每一个DecorView的位置可以通过 android:layout_gravity属性来控制,例如:
<android.support.v4.view.ViewPager android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v4.view.PagerTitleStrip android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="top" /> </android.support.v4.view.ViewPager>
翻译有点潦草,大致的意思应该是这样~
类结构
常用成员的功能介绍
成员 | 功能 |
---|---|
ViewPager() | 构造方法 |
addOnAdapterChangeListener | 添加一个OnAdapterChangeListener |
removeOnAdapterChangeListener | 移除一个OnAdapterChangeListener |
setCurrentItem | 设置当前Pager的index |
addOnePageChangeListener | 设置一个页面改变监听器 |
addOnePageChangeListener | 移除一个页面改变监听器 |
clearOnPageChangeListener | 移除所有的页面改变监听器 |
setPageTransformer | 设置页面之间切换的过程中的PageTransformer |
实际使用
1. 简单显示
布局文件<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="mraz.com.opensourcedemo.MainActivity"> <android.support.v4.view.ViewPager android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/viewpager" > </android.support.v4.view.ViewPager> </RelativeLayout>
代码内容
MainActivity.java
package mraz.com.opensourcedemo; import android.support.v4.view.ViewPager; import android.support.v4.widget.ViewDragHelper; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.Window; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { ArrayList<String> sourceList; private static final float MIN_SCALE = 0.5f; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager); MyPagerAdapter myPagerAdapter = new MyPagerAdapter(getSupportFragmentManager()); viewPager.setAdapter(myPagerAdapter); } }
Adapter类
package mraz.com.opensourcedemo; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; /** * Created by Mraz on 2016/7/8. */ public class MyPagerAdapter extends FragmentPagerAdapter { public static final String[] titles = {"Android"," Pet","Gift"}; public MyPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { switch (position) { case 0: return new FirstFragment(); case 1: return new SecondFragment(); case 2: return new ThreeFragment(); } return null; } @Override public int getCount() { return 3; } }
MyPagerAdapter 继承FragmentPagerAdapter,当创建这个类并继承FragmentPagerAdapter的时候,AS会提示开发者需要实现两个方法,并且要添加一个构造函数,getItem就是根据位置返回对应的Fragment,getCount就是返回页面数,这里我是直接返回的对应的内容,数目也是固定的,在实际开发过程中,使用ArrayList等数据结构来传递合适的参数,可以更灵活的设置Adapter的内容,使ViewPager的内容更丰富。这里的 FirstFragment,SecondFragment,ThreeFragment内容只是一个简单的图片资源,对应的布局文件也比较简单,不贴代码了。
实际效果
2. 添加PageTransformer
代码内容private static final float MIN_SCALE = 0.5f; ... viewPager.setPageTransformer(true, new ViewPager.PageTransformer() { @Override 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 + position); view.setTranslationX(0); float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position)); view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); } 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); } } });
上面是参照例子写的一个页面切换效果,主要关注的是透明度和大小的改变,在页面切换的过程中,对于离开的页面变透明,变小,进入的页面变明显,变大。看下ViewPager.PageTransformer这个接口
/** * 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,传入的参数,第一个参数是页面视图,第二个参数很重要,指的是当前页面所处的一种状态,根据position来判断,我们添加的所有效果,都是要依据这个值来做处理,当我们滑动页面的时候,这个值在不停的变化,并且不同的page的值不相同。
取值 | 含义 |
---|---|
[-Infinity,-1) | 这个范围的视图已经看不见了 |
[-1,0] | 即将退出界面的page的变化范围,从0慢慢变成-1 |
[0,1] | 即将进入界面的page的变化范围,从1慢慢变成0 |
(1,+Infinity] | 这个范围的视图已经看不见了 |
实际效果
3. 添加OnPageChangeListener
代码内容viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { Log.e(TAG, "onPageScrolled position = " + position + " positionOffset = " + positionOffset + " positionOffsetPixels = " + positionOffsetPixels); } @Override public void onPageSelected(int position) { Log.e(TAG, "onPageSelected position = " + position); } @Override public void onPageScrollStateChanged(int state) { Log.e(TAG, "onPageScrollStateChanged state = " + state); } });
可以看到当滑动页面的时候,会有一大串的Log打印出来
看下OnPagerChangeListener这个接口的定义
/** * Callback interface for responding to changing state of the selected page. */ public interface OnPageChangeListener { /** * This method will be invoked when the current page is scrolled, either as part * of a programmatically initiated smooth scroll or a user initiated touch scroll. * * @param position Position index of the first page currently being displayed. * Page position+1 will be visible if positionOffset is nonzero. * @param positionOffset Value from [0, 1) indicating the offset from the page at position. * @param positionOffsetPixels Value in pixels indicating the offset from position. */ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels); /** * This method will be invoked when a new page becomes selected. Animation is not * necessarily complete. * * @param position Position index of the new selected page. */ public void onPageSelected(int position); /** * Called when the scroll state changes. Useful for discovering when the user * begins dragging, when the pager is automatically settling to the current page, * or when it is fully stopped/idle. * * @param state The new scroll state. * @see ViewPager#SCROLL_STATE_IDLE * @see ViewPager#SCROLL_STATE_DRAGGING * @see ViewPager#SCROLL_STATE_SETTLING */ public void onPageScrollStateChanged(int state); }
指的一提的是 positionOffset 这个参数可以在onPageScrolled回调中拿到,而这个数值呢 就是和我们上面自定义过场的时候用到的 transformPage方法中传入的第二个参数position 有联系,只是这里的positionOffset取值范围为[0, 1),上面的position中取值范围更广,但是从实际上来看,对我们影响比较大的就是当前切换的两个Page,也就是[-1,1]这个取值范围,所谓的负值可以理解成是相对概念,所以,这两个变量之间是存在关系的,如果不理解上面PageTransformer, 可以结合这个positionOffset变量的打印值加以理解。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories