<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 构造方法-无参构造方法 本文知识点:构造方法-无参构造方法 说明:因为时间紧张, ...
随机推荐
- P1900 自我数
题意: 对于每一个正整数n,我们定义d(n)为n加上它每一位数字的和. 例如,d(75)=75+7+5=87.给定任意正整数n作为一个起点,都能构造出一个无限递增的序列:n, d(n), d(d(n) ...
- P2723 丑数 Humble Numbers
题意:给你k个质数,定义丑数集合为k个质数随机(1--k)个相乘得到的数 求第n小的丑数 暴力...貌似不太可行,(把所有大量丑数求出来,sort QAQ) 可以想到,对于第i个丑数f[i],它一 ...
- socket中close发生的事情,RST,pipe信号错误
1.server端close之后,client端write,导致server端发送RST(服务器关闭套接字):对方已经关闭或者异常终止,但是client端,不知道,这个成为半打开 当server端cl ...
- pytorch实现depthwise convolution
深度分离卷积是Xception这个模型中提出来的(不太确定,但肯定是它让这个概念为大众周知),具体来说分为两步,depthwise conv和pointwise conv,前者对输入特征图的每个通道进 ...
- 项目笔记《DeepLung:Deep 3D Dual Path Nets for Automated Pulmonary Nodule Detection and Classification》(一)预处理
最近一个月都在做肺结节的检测,学到了不少东西,运行的项目主要是基于这篇论文,在github上可以查到项目代码. 我个人总结的肺结节检测可以分为三个阶段,数据预处理,网络搭建及训练,结果评估. 这篇博客 ...
- python 批量修改包名
#coding=utf-8 import os #import re # 设置编码为utf-8 否则会报错..这时候 sublime控制台会报乱码.但是别担心,utf-8 文件 并不会报错 impor ...
- Hello World 十大秘密
#include <stdio.h> int main(int argc, char* argv[], char* env[]) { printf("Hello World\n& ...
- Python 初识爬虫-**机场出港业务
# -*- coding:utf-8 -*- from lxml import etree import requests ##先进单页测试,然后在进行多页循环 没有解决的问题,动态解决最大页数,目前 ...
- Launch iCar Scan Android Scanner Support Bluetooth X431 iDiag Update Version
Autonumen.com release new Launch iCar Scan for Android,Launch iCarScan Bluetooth Scanner is update v ...
- 关于element-ui表格样式设置的方法cell-class-name
关于element-ui表格使用的一些方法 最近在用Vue.js和elment-ui做一个后台管理项目,不得不说element功能非常强大,提供了许多组件,基本可以满足一些基础的开发了.因为我做的后台 ...