ViewPager学习及使用(一)
一:基础篇
1.ViewPager的简介和作用
ViewPager是android扩展包v4包中的类,这个类可以让用户左右切换当前的view
1)ViewPager类直接继承了ViewGroup类,所有它是一个容器类,可以在其中添加其他的view类。
2)ViewPager类需要一个PagerAdapter适配器类给它提供数据。
3)ViewPager经常和Fragment一起使用,并且提供了专门的FragmentPagerAdapter和FragmentStatePagerAdapter类供Fragment中的ViewPager使用。
2.ViewPager的适配器
简介中提到了PagerAdapter,和ListView等控件使用一样,需要ViewPager设置PagerAdapter来完成页面和数据的绑定,这个PagerAdapter是一个基类适配器,我们经常用它来实现app引导图,它的子类有FragmentPagerAdapter和FragmentStatePagerAdapter,这两个子类适配器用于和Fragment一起使用,在安卓应用中它们就像listview一样出现的频繁。
实现一个最基本的PagerAdapter,《必须实现四个方法》,在代码里有注释
public class AdapterViewpager extends PagerAdapter {
private List<View> mViewList;
public AdapterViewpager(List<View> mViewList) {
this.mViewList = mViewList;
}
@Override
public int getCount() {//必须实现
return mViewList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {//必须实现
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {//必须实现,实例化
container.addView(mViewList.get(position));
return mViewList.get(position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {//必须实现,销毁
container.removeView(mViewList.get(position));
}
}
实现一个最基本的FragmentPagerAdapter
public class AdapterFragment extends FragmentPagerAdapter {
private List<Fragment> mFragments;
public AdapterFragment(FragmentManager fm, List<Fragment> mFragments) {
super(fm);
this.mFragments = mFragments;
}
@Override
public Fragment getItem(int position) {//必须实现
return mFragments.get(position);
}
@Override
public int getCount() {//必须实现
return mFragments.size();
}
@Override
public CharSequence getPageTitle(int position) {//选择性实现
return mFragments.get(position).getClass().getSimpleName();
}
}
FragmentStatePagerAdapter的实现和FragmentPagerAdapter的实现一样就不在写了
3个适配器的基本实现讲完了是不是很简单,那他们的区别是什么呢?
PagerAdapter是基类适配器是一个通用的ViewPager适配器,相比PagerAdapter,FragmentPagerAdapter和FragmentStatePagerAdapter更专注于每一页是Fragment的情况,而这两个子类适配器使用情况也是有区别的。FragmentPagerAdapter适用于页面比较少的情况,FragmentStatePagerAdapter适用于页面比较多的情况。为什么?简单分析下两个适配器的源码就可以知道了。
FragmentStatePagerAdapter
@Override
public Object instantiateItem(ViewGroup container, int position) {
// If we already have this item instantiated, there is nothing
// to do. This can happen when we are restoring the entire pager
// from its saved state, where the fragment manager has already
// taken care of restoring the fragments we previously had instantiated.
if (mFragments.size() > position) {
Fragment f = mFragments.get(position);//fragment被释放后这里得到的null值
if (f != null) {
return f;
}
} if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
} Fragment fragment = getItem(position);//fragment被释放后或者是初次进入页面拿到新的Fragment实例
if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment);
if (mSavedState.size() > position) {
Fragment.SavedState fss = mSavedState.get(position);
if (fss != null) {
fragment.setInitialSavedState(fss);
}
}
while (mFragments.size() <= position) {
mFragments.add(null);
}
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
mFragments.set(position, fragment);
mCurTransaction.add(container.getId(), fragment);//新的Fragment实例 是add上去的 return fragment;
} @Override
public void destroyItem(ViewGroup container, int position, Object object) {
Fragment fragment = (Fragment) object; if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
if (DEBUG) Log.v(TAG, "Removing item #" + position + ": f=" + object
+ " v=" + ((Fragment)object).getView());
while (mSavedState.size() <= position) {
mSavedState.add(null);
}
mSavedState.set(position, fragment.isAdded()
? mFragmentManager.saveFragmentInstanceState(fragment) : null);
mFragments.set(position, null);//真正释放了fragment实例 mCurTransaction.remove(fragment);
}
FragmentPagerAdapter
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
} final long itemId = getItemId(position); // Do we already have this fragment?
String name = makeFragmentName(container.getId(), itemId);
Fragment fragment = mFragmentManager.findFragmentByTag(name);
if (fragment != null) {
if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
mCurTransaction.attach(fragment);//因为fragment实例没有被真正释放,所以可以直接attach效率高
} else {
fragment = getItem(position);//初始化页面的时候拿到fragment的实例
if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
mCurTransaction.add(container.getId(), fragment,
makeFragmentName(container.getId(), itemId));//add上去
}
if (fragment != mCurrentPrimaryItem) {
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
} return fragment;
} @Override
public void destroyItem(ViewGroup container, int position, Object object) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object
+ " v=" + ((Fragment)object).getView());
mCurTransaction.detach((Fragment)object);//并没有真正释放fragment对象只是detach
}
从源码中我们可以看出FragmentStatePagerAdapter中fragment实例在destroyItem的时候被真正释放,所以FragmentStatePagerAdapter省内存。FragmentPagerAdapter中的fragment实例在destroyItem的时候并没有真正释放fragment对象只是detach,所以FragmentPagerAdapter消耗更多的内存,带来的好处就是效率更高一些。所以得出这样的结论:FragmentPagerAdapter适用于页面比较少的情况,FragmentStatePagerAdapter适用于页面比较多的情况,因此不同的场合选择合适的适配器才是正确的做法
3.ViewPager的翻页动画
为ViewPager设置适配器后,就可以正常使用了,接下来我们为ViewPager增加翻页动画,毕竟人的审美会疲劳,加上一些动画交互会提高不少逼格~~,ViewPager提供了PageTransformer接口用于实现翻页动画。
官方提供了PageTransformer的实现例子。
原文:http://www.jianshu.com/p/e5abbda4a71c
ViewPager学习及使用(一)的更多相关文章
- 【转】ViewPager学习笔记(一)——懒加载
在项目中ViewPager和Fragment接口框架已经是处处可见,但是在使用中,我们肯定不希望用户在当前页面时就在前后页面的数据,加入数据量很大,而用户又不愿意左右滑动浏览,那么这时候ViewPag ...
- [转]ViewPager学习笔记(一)——懒加载
在项目中ViewPager和Fragment接口框架已经是处处可见,但是在使用中,我们肯定不希望用户在当前页面时就在前后页面的数据,加入数据量很大,而用户又不愿意左右滑动浏览,那么这时候ViewPag ...
- 安卓开发之viewpager学习(头条显示)
activity_luancher.xml代码如下: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res ...
- ViewPager学习之仿微信主界面
由于素材的原因,这里都是从网上找的图片,所以所谓的仿微信实际上最后成了下图这货.. .,点击变色也是自己用的windows自带绘图的颜料桶填充的空白. .. watermark/2/text/aHR0 ...
- Android -- ViewPager、Fragment、状态保存、通信
工程架构 TabAFm到Tab ...
- (转载)Android引导界面实现
Android引导界面实现 Android 2014-07-10 14:47:36 发布 您的评价: 4.0 收藏 3收藏 ViewPager类提供了多界面切换的新效果,是 ...
- 安卓开发_深入学习ViewPager控件
一.概述 ViewPager是android扩展包v4包(android.support.v4.view.ViewPager)中的类,这个类可以让用户左右切换当前的view. ViewPager特点: ...
- android学习ViewPager的简单使用
使用ViewPager需要引入android.support.v4.View.ViewPager这样的jar包,谷歌公司为解决当前版本碎片化的问题,提供的兼容的包.主要目的就是解决向下兼容问题. 1, ...
- ViewPager适配器学习记录( pageAdapter和FragmentPagerAdapter/FragmentStatePagerAdapter))
1.概述 ViewPager,顾名思义实现控件的滚动功能,是Support-v4的包中类,使用前要先导包.使用的时候跟listView有点相似,需要设置对应的适配器,通常有俩大类 [pageAdapt ...
随机推荐
- 浅谈配置文件:spring-servlet.xml(spring-mvc.xml) 与 applicationContext.xml
在搭建 spring mvc 的框架时,会有2个配置文件必不可少: spring-servlet.xml 和applicationContext.xml.第一次接触spring mvc的工程师可能会对 ...
- RabbitMQ学习之:(一)初识、概念及心得
因为网上有一篇很好的RMQ的入门帖子http://lostechies.com/derekgreer/tag/rabbitmq/,所以我就不多说了,就说说我目前看了该作者1~5章后,自己的心得.(所以 ...
- 推广Facebook技巧
1.创建有吸引力的内容发布多样化的内容,包括图片,状态更新,视频,投票等.可以问你的粉丝一些问题让他们提供答案.这些内容不仅你的粉丝可以看到,它们还将会出现在你粉丝的个人动态栏,所以他们的朋友也是可以 ...
- java 线程之间的协作 wait()与notifyAll()
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlhbmdydWkxOTg4/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...
- 使用AngularJS创建应用的5个框架
[导读] 如果你计划使用AngularJS创建你的Web应用,那现在就开始吧.你不需要有任何的恐惧和担心,因为现在有很多的框架都可以很好地支持AngularJS.这些框架都有事先安装的Web组件,使用 ...
- EJB EJB定义了一组可重用的组件:Enterprise Beans
EJB EJB定义了一组可重用的组件:Enterprise Beans.开发人员可以利用这些组件,像搭积木一样建立分布式应用.
- C#从Excel中读取数据为空
将HDR设置为YES,IMEX设置为1即可. OleDbConnection objConn = new OleDbConnection("Provider=Microsoft.ACE.OL ...
- unity 打开文件夹并鼠标选中某文件
System.Diagnostics.Process p = new System.Diagnostics.Process(); p.StartInfo.FileName = "explor ...
- java -Mac搭建本地服务器并映射到外网
最近在学习Html,小有进步变想着写一个浪漫的静态页面给女朋友浪漫一下,那么问题就来了,如何把我的网页让对网络一窍不通的女朋友看到,所以便想到了是用自己电脑作为服务器的想法.百度以后整理如下: 首先搭 ...
- Android 实现个性的ViewPager切换动画 实战PageTransformer(兼容Android3.0下面)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/40411921.本文出自:[张鸿洋的博客] 1.概述 之前写过一篇博文:Andro ...