<Android 基础(十七)> ViewPager介绍
介绍
Layout manager that allows the user to flip left and right
through 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 |
其他的一些方法从使用程度上来看比较的少见,源码内容大家通过AS都是可以查看到的。
实际使用
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变量的打印值加以理解。
<Android 基础(十七)> ViewPager介绍的更多相关文章
- 【Android 复习】:第01期:引导界面(一)ViewPager介绍和使用详解
一.ViewPager实现的效果图 二.ViewPager实现的功能 看到上面的效果图,想必大家已经猜出了这个类是干吗用的了,ViewPager类提供了多界面切换的新效果, 新效果有如下特征: < ...
- Android 基础:常用布局 介绍 & 使用(附 属性查询)
Android 基础:常用布局 介绍 & 使用(附 属性查询) 前言 在 Android开发中,绘制UI时常需各种布局 今天,我将全面介绍Android开发中最常用的五大布局 含 Andr ...
- Android基础-系统架构分析,环境搭建,下载Android Studio,AndroidDevTools,Git使用教程,Github入门,界面设计介绍
系统架构分析 Android体系结构 安卓结构有四大层,五个部分,Android分四层为: 应用层(Applications),应用框架层(Application Framework),系统运行层(L ...
- 【Android UI设计与开发】第01期:引导界面(一)ViewPager介绍和使用详解
做Android开发加起来差不多也有一年多的时间了,总是想写点自己在开发中的心得体会与大家一起交流分享.共同进步,刚开始写也不知该如何下手,仔细想了一下,既然是刚开始写,那就从一个软件给人最直观的感受 ...
- android开发学习---linux下开发环境的搭建&& android基础知识介绍
一.配置所需开发环境 1.基本环境配置 JDK 5或以上版本(仅有JRE不够) (http://www.oracle.com/technetwork/java/javase/downloads/ind ...
- 085 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 04 构造方法调用
085 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 04 构造方法调用 本文知识点:构造方法调用 说明:因为时间紧张,本人写博客过程中只是 ...
- 084 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 03 构造方法-this关键字
084 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 03 构造方法-this关键字 本文知识点:构造方法-this关键字 说明:因为时间紧 ...
- 083 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 02 构造方法-带参构造方法
083 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 02 构造方法-带参构造方法 本文知识点:构造方法-带参构造方法 说明:因为时间紧张, ...
- 082 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 01 构造方法-无参构造方法
082 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 01 构造方法-无参构造方法 本文知识点:构造方法-无参构造方法 说明:因为时间紧张, ...
随机推荐
- P4094 [HEOI2016/TJOI2016]字符串 后缀数组+主席树+二分答案
$ \color{#0066ff}{ 题目描述 }$ 佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了一个长为n的字符串s,和m个问题.佳媛姐姐必须 ...
- luogu1447 [NOI2010]能量采集 莫比乌斯反演
link 冬令营考炸了,我这个菜鸡只好颓废数学题了 NOI2010能量采集 由题意可以写出式子: \(\sum_{i=1}^n\sum_{j=1}^m(2\gcd(i,j)-1)\) \(=2\sum ...
- log4j配置文件及java调用 每个级别输出到不同的文件
#配置根Logger log4j.rootLogger = DEBUG , RollingFile,CONSOLE #文件大小达到一定尺寸的时候创建一个新的文件 log4j.appender.Roll ...
- Servlet中Web.xml的配置详解(一)
1 定义头和根元素 部署描述符文件就像所有XML文件一样,必须以一个XML头开始.这个头声明可以使用的XML版本并给出文件的字符编码.DOCYTPE声明必须立即出现在此头之后.这个声明告诉服务器适用的 ...
- 远程私有库的创建 pod 组件化
参考: http://www.cnblogs.com/hs-funky/p/6780203.html http://www.jianshu.com/p/4b63dfbd8be7 http://ww ...
- vue.js路由学习笔记二
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- 关于AppiumDriver
java client2.0之后把AppiumDriver作为抽象类,IOSDriver和AndroidDriver继承AppiumDriver.安卓端就用AndroidDriver.2.0之前And ...
- vs快捷键(SharePoint项目)
1.ctrl+c,alt+c,shift+ctrl+c: ========== Copying to SharePoint Root =========={ProjectRoot}\pkg\Debug ...
- Vue全家桶了解一下(待补充)
vue全家桶了解一下 一.vue+vue-router+vuex+axios1.vue:使用vue-cli,生成最基本的vue项目2.vue-router:vue项目中的路由管理插件3.vuex:vu ...
- 可视化开发_AppInventor2似乎被抛弃了
工具 blockly google,mixly,scratch,app inventor2 的分别 可视化编程,青雀,来自 白鹭 没源码 如果想二次开发呢,初版拖拽控件生成,后期维护的时候找程序员加功 ...