一、概述

ViewPager是android-support-v4中提供的类,它是一个容器类,常用于页面之间的切换。

本文介绍ViewPager最基础的应用:在多个View之间进行切换,亦即ViewPager的每个页面是个View。

这种模式适合每个页面的逻辑较为简单的情况,比如去实现“小红书”引导页这样的效果:

二、实现思路

2.1 页面如何布局

这个引导页一共有三个页面,毫无疑问上面的标题和配图是隶属于viewpager不同页面内部的,而下面的俩按钮则是直接放在Activity的布局中。

那indicator呢?虽然在不同的页面红点的位置不一样,但它不能放在页面的布局中,否则,三个点就会跟配图一样整体滑动了……

2.2 代码如何实现

ViewPager是什么鬼呢?其实它就是个ViewGroup,用法跟ListView类似,重点在于实现这样一个Adapter:

     private class ViewPagerAdapter extends PagerAdapter {
@Override
public int getCount() {
return 0; //ViewPager总共有几个页面
} @Override
public boolean isViewFromObject(View view, Object object) {
return false; //判断一个页面(View)是否与instantiateItem方法返回的Object一致
} @Override
public Object instantiateItem(ViewGroup container, int position) {
return super.instantiateItem(container, position); //创建一个页面
} @Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object); //销毁一个页面
}
}

[转载请保留本文地址:http://www.cnblogs.com/snser/p/5700751.html]

三、开始干活

3.1 摆出activity和每个页面的布局

viewpager_view.xml (activity的布局)

 <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"
android:background="@drawable/viewpager_view_bg"
tools:context="${relativePackage}.${activityClass}" > <android.support.v4.view.ViewPager
android:id="@+id/viewpager_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/viewpager_view_bg" /> <ImageView
android:id="@+id/viewpager_view_point"
android:layout_width="66.7dp"
android:layout_height="10dp"
android:layout_centerHorizontal="true"
android:layout_above="@+id/viewpager_view_register"
android:layout_marginBottom="20dp"
android:src="@drawable/viewpager_view_point_1" /> <Button
android:id="@+id/viewpager_view_register"
android:layout_width="190dp"
android:layout_height="45dp"
android:layout_centerHorizontal="true"
android:layout_above="@+id/viewpager_view_login"
android:layout_marginBottom="10dp"
android:background="@drawable/viewpager_view_register_bg"
android:textSize="19sp"
android:textColor="#FFFFFF"
android:text="@string/viewpager_view_register" /> <Button
android:id="@+id/viewpager_view_login"
android:layout_width="190dp"
android:layout_height="45dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="50dp"
android:background="@drawable/viewpager_view_login_bg"
android:textSize="19sp"
android:textColor="#999999"
android:text="@string/viewpager_view_login" /> </RelativeLayout>

viewpager_view_page.xml (页面的布局):

 <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="${relativePackage}.${activityClass}" > <TextView
android:id="@+id/viewpager_view_page_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_centerHorizontal="true"
android:textSize="20sp"
android:textColor="#333333"
android:text="@string/viewpager_view_page_title_1" /> <ImageView
android:id="@+id/viewpager_view_page_content"
android:visibility="visible"
android:layout_width="match_parent"
android:layout_height="385dp"
android:layout_marginTop="75dp"
android:layout_gravity="center_horizontal"
android:scaleType="centerInside"
android:src="@drawable/viewpager_view_page_content_1" /> </RelativeLayout>

3.2 简要介绍一下即将出炉的核心代码

 public class ViewPagerViewActivity extends Activity implements View.OnClickListener {

     private ViewPager mPager;
private ImageView mImgPoint; private SparseArray<View> mPageCache = new SparseArray<View>(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewpager_view);
initView();
} private void initView() {
mPager = (ViewPager)findViewById(R.id.viewpager_view_pager);
mImgPoint = (ImageView)findViewById(R.id.viewpager_view_point);
mPager.setAdapter(new ViewPagerAdapter(ViewPagerViewActivity.this));
mPager.addOnPageChangeListener(new OnViewPageChangeListener());
findViewById(R.id.viewpager_view_register).setOnClickListener(this);
findViewById(R.id.viewpager_view_login).setOnClickListener(this);
} private class ViewPagerAdapter extends PagerAdapter {
private final int mCount = 3;
private LayoutInflater mInflater; private ViewPagerAdapter(Context context) {
mInflater = LayoutInflater.from(context);
} @Override
public int getCount() {
return mCount;
} @Override
public boolean isViewFromObject(View view, Object obj) {
return view == obj;
} @Override
public Object instantiateItem(ViewGroup container, int position) {
View page = mPageCache.get(position);
if (page == null) {
page = mInflater.inflate(R.layout.viewpager_view_page, container, false);
TextView txtTitle = (TextView)page.findViewById(R.id.viewpager_view_page_title);
ImageView imgContent = (ImageView)page.findViewById(R.id.viewpager_view_page_content);
switch (position) {
case 0:
txtTitle.setText(R.string.viewpager_view_page_title_1);
imgContent.setImageResource(R.drawable.viewpager_view_page_content_1);
break;
case 1:
txtTitle.setText(R.string.viewpager_view_page_title_2);
imgContent.setImageResource(R.drawable.viewpager_view_page_content_2);
break;
case 2:
txtTitle.setText(R.string.viewpager_view_page_title_3);
imgContent.setImageResource(R.drawable.viewpager_view_page_content_3);
break;
default:
break;
}
mPageCache.append(position, page);
}
container.addView(page);
return page;
} @Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View)object);
}
} private class OnViewPageChangeListener implements OnPageChangeListener {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
} @Override
public void onPageSelected(int position) {
switch (position) {
case 0:
mImgPoint.setImageResource(R.drawable.viewpager_view_point_1);
break;
case 1:
mImgPoint.setImageResource(R.drawable.viewpager_view_point_2);
break;
case 2:
mImgPoint.setImageResource(R.drawable.viewpager_view_point_3);
break;
default:
break;
}
} @Override
public void onPageScrollStateChanged(int state) {
}
} @Override
public void onClick(View v) {
finish();
}
}

重点关注下 ViewPagerAdapter :

在 instantiateItem 方法中会inflate出新的页面,再根据不同的position对页面进行对应的初始化工作,同时在ViewPager中添加当前页面。

而在 destroyItem 方法中,只需要将当前页面从ViewPager中移除即可。

同时,需要给ViewPager设置一个 OnPageChangeListener ,以便在页面切换的时候更新Indicator对应的小红点位置。

3.3 关于缓存

可以看到,上面的代码在 instantiateItem 方法中用到了页面缓存,亦即每个position对应的页面只需要inflate一次。

那为什么会有缓存的需求呢?这是因为ViewPager每次加载当前页面的同时,会自动预加载(instantiateItem)与当前页面左右相隔的两个页面,同时会销毁(destroyItem)与当前页面不相邻的页面。

设想一下,滑动到第三个页面时,第一个页面会被销毁掉,而滑回第二个页面时,又会重新创建第一个页面。如果不加以缓存,就会造成页面的重复inflate从而浪费资源、降低性能。

[转载请保留本文地址:http://www.cnblogs.com/snser/p/5700751.html]

四、demo工程

保存下面的图片,扩展名改成 .zip 即可

 [转载请保留本文地址:http://www.cnblogs.com/snser/p/5700751.html] 

ViewPager之引导页的更多相关文章

  1. ViewPager实现引导页

    1. 要使用ViewPager,必须要创建 PagerAdapter. 这里创建一个 ViewPagerAdapter来继承PagerAdapter public class ViewPagerAda ...

  2. ViewPager实现引导页(添加导航点,判断是否第一次进入主界面)

    1.引导页的4个界面布局,里面加载一张背景图片 插入到guide的界面布局中(这里不用fragment) guide_background_fragment1.xml <?xml version ...

  3. ViewPager滑动引导页

    ViewPager实现Animation动画引导页   http://blog.csdn.net/ye_scofield/article/details/44831357 SurfaceView实现动 ...

  4. ViewPager—01引导页的制作

    布局文件 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:t ...

  5. 安卓第一次启动引导页使用ViewPager实现

    我们在安装某个APP的时候,基本都会有一个引导页的提示,他们可以打广告,或者介绍新功能的加入和使用说明等.一般都支持滑动并且下面有几个点,显示共有多少页和当前图片的位置,在IOS上这个实现起来比较简单 ...

  6. ViewPager打造轮播图(Banner)\引导页(Guide)

    今年7月时,在Github发布了一个开源的Banner库,虽然Star不多,但还是有少部分人使用. Banner效果:  昨天,有使用此库的同学提出需求,想在引导页的时候用这个库并且最后一页有进入按钮 ...

  7. Android ViewPager欢迎页+引导页+进入首页

    import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences ...

  8. android使用ViewPager实现欢迎引导页

    android使用ViewPager实现欢迎引导页 大多数APP第一次启动的时候,都会有一个引导界面,左右滑动,到最后一张,用户点击才再次进入主界面.当第二次启动的时候,则直接进入主界面. 这种效果一 ...

  9. Android特效专辑(二)——ViewPager渲染背景颜色渐变(引导页)

    Android特效专辑(二)--ViewPager渲染背景颜色渐变(引导页) 首页:http://blog.csdn.net/qq_26787115/article/details/50439020 ...

随机推荐

  1. 跨平台的 .NET 运行环境 Mono 3.2 新特性

    Mono 3.2 发布了,对 Mono 3.0 和 2.10 版本的支持不再继续,而且这两个分支也不再提供 bug 修复更新. Mono 3.2 主要新特性: LLVM 更新到 3.2 版本,带来更多 ...

  2. 从is(":checked")说起

    *此文所用jQuery版本应大于1.6.1   如何判断一个单选(复选)框是否选中. 对于刚接触jQuery的人,第一反应必然是. <input id="checkbox1" ...

  3. Netty构建分布式消息队列(AvatarMQ)设计指南之架构篇

    目前业界流行的分布式消息队列系统(或者可以叫做消息中间件)种类繁多,比如,基于Erlang的RabbitMQ.基于Java的ActiveMQ/Apache Kafka.基于C/C++的ZeroMQ等等 ...

  4. smartcrop.js智能图片裁剪库

    今天将为大家介绍一款近期github上很不错的开源库 – smartcrop.js.它是一款图片处理的智能裁剪库.在很多项目开发中,经常会遇见上传图片的场景,它可能是用户照片信息,也可能是商品图片等. ...

  5. 浅谈C#网络编程(二)

    阅读目录: 异步IO 非阻塞式同步IO 基于回调的异步IO并发 异步IO 上篇提到用多线程处理多个阻塞同步IO而实现并发服务端,这种模式在连接数量比较小的时候非常适合,一旦连接过多,性能会急速下降. ...

  6. .NET深入实战系列--EF到底怎么写过滤条件

    本文唯一访问地址:http://www.cnblogs.com/yubaolee/p/DynamicLinq.html 对于系统开发来说,按不同字段进行过滤查询是一种常见的需求.在EF中通常的做法是: ...

  7. 一缕阳光:DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?

    写在前面 阅读目录: 问题根源是什么? <领域驱动设计-软件核心复杂性应对之道>分层概念 Repository(仓储)职责所在? Domain Model(领域模型)重新设计 Domain ...

  8. javascript中的浮点数运算

    解释一下下面代码的输出 console.log(0.1 + 0.2); //0.30000000000000004 console.log(0.1 + 0.2 == 0.3); //false Jav ...

  9. 解析大型.NET ERP系统 界面与逻辑分离

    Windows Forms程序实现界面与逻辑分离的关键是数据绑定技术(Data Binding),这与微软推出的ASP.NET MVC的原理相同,分离业务代码与界面层,提高系统的可维护性. 数据绑定 ...

  10. H5+JS+CSS3 综合应用

    慕课网新教程H5+JS+CSS3 实现的七夕言情主题效果已经出炉了 从设计到实现到录制与编写用了快1个月的时间,说真的这个案例是慕课定制的,我之前也没有系统的做过这样的一个效果,在实现的时候自己也重新 ...