ViewPager 详解(五)-----使用Fragment实现ViewPager滑动
前言:前几篇文章讲解了ViewPager的普通实现方法,但Android官方最推荐的一种实现方法却是使用fragment,下面我们使用fragment来重新实现一下第一篇《ViewPager 详解(一)---基本入门》所实现的效果。
系列文章:
3、《ViewPager 详解(三)---PagerTabStrip与PagerTitleStrip添加标题栏的异同》
4、《ViewPager 详解(四)----自主实现滑动指示条》
其它相关文章:
5、《Android Fragment完全解析,关于碎片你所需知道的一切》
6、《fragment中嵌套viewpager,vierpager中有多个fragment》
本篇效果图:
在第一个页面加一个Btn 第一页面向第二页面滑动
第二页面向第三个页面滑动
一、概述
从前面几篇文章,我们知道,实现ViewPager是要有适配器的,我们前面用的适配器是PagerAdapter,而对于fragment,它所使用的适配器是:FragmentPagerAdapter.先看看官方对于这个类的解释:(英文下面有中文解释)
原文:
Class Overview
Implementation of PagerAdapter
that represents each page as a Fragment
that is persistently kept in the fragment manager as long as the user can return to the page.
This version of the pager is best for use when there are a handful of typically more static fragments to be paged through, such as a set of tabs. The fragment of each page the user visits will be kept in memory, though its view hierarchy may be destroyed when not visible. This can result in using a significant amount of memory since fragment instances can hold on to an arbitrary amount of state. For larger sets of pages, consider FragmentStatePagerAdapter
.
When using FragmentPagerAdapter the host ViewPager must have a valid ID set.
Subclasses only need to implement getItem(int)
and getCount()
to have a working adapter.
译文:(译的不好,大家可在评论中补充)
FragmentPagerAdapter派生自PagerAdapter,它是用来呈现Fragment页面的,这些Fragment页面会一直保存在fragment manager中,以便用户可以随时取用。
这个适配器最好用于有限个静态fragment页面的管理。尽管不可见的视图有时会被销毁,但用户所有访问过的fragment都会被保存在内存中。因此fragment实例会保存大量的各种状态,这就造成了很大的内存开销。所以如果要处理大量的页面切换,建议使用FragmentStatePagerAdapter.
每一个使用FragmentPagerAdapter的ViewPager都要有一个有效的ID集合,有效ID的集合就是Fragment的集合(感谢夫诸同学的提示)
对于FragmentPagerAdapter的派生类,只需要重写getItem(int)和getCount()就可以了。
二、具体实现
1、适配器实现——FragmentPagerAdapter
先看完整代码,再细讲:
- public class FragAdapter extends FragmentPagerAdapter {
- private List<Fragment> mFragments;
- public FragAdapter(FragmentManager fm,List<Fragment> fragments) {
- super(fm);
- // TODO Auto-generated constructor stub
- mFragments=fragments;
- }
- @Override
- public Fragment getItem(int arg0) {
- // TODO Auto-generated method stub
- return mFragments.get(arg0);
- }
- @Override
- public int getCount() {
- // TODO Auto-generated method stub
- return mFragments.size();
- }
- }
这里有三个函数,根据第一部分的官方文档,可知,对于FragmentPagerAdapter的派生类,只重写getItem(int)和getCount()就可以了。
对于构造函数,这里申请了一个Fragment的List对象,用于保存用于滑动的Fragment对象,并在创造函数中初始化:
- public FragAdapter(FragmentManager fm,List<Fragment> fragments) {
- super(fm);
- // TODO Auto-generated constructor stub
- mFragments=fragments;
- }
然后在getItem(int arg0)中,根据传来的参数arg0,来返回当前要显示的fragment,下面是getItem的官方解释,难度不大,不再细讲。
public abstract Fragment getItem (int position)
Return the Fragment associated with a specified position.
最后,getCount()返回用于滑动的fragment总数;
从构造函数所以看出,我们要构造Fragment的集合才行,所以下面我们就先产生我们所需要的Fragment类;
2、三个Fragment类
第一个Fragment类:
XML:(layout1.xml)
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#ffffff"
- android:orientation="vertical" >
- <Button android:id="@+id/fragment1_btn"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="show toast"
- />
- </LinearLayout>
在其中加入了一个Btn
Java代码:
- public class Fragment1 extends Fragment {
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- View view= inflater.inflate(R.layout.layout1, container, false);
- //对View中控件的操作方法
- Button btn = (Button)view.findViewById(R.id.fragment1_btn);
- btn.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- Toast.makeText(getActivity(), "点击了第一个fragment的BTN", Toast.LENGTH_SHORT).show();
- }
- });
- return view;
- }
- }
在onCreateView()中返回要显示的View,上面这段代码简单演示了如何对视图里的控件进行操作,难度不大,不再细讲,如果对Fragment不太熟悉的同学,先看看这篇文章:《Android Fragment完全解析,关于碎片你所需知道的一切》
第二个Fragment类:
XML代码:(layout2.xml)原生代码,没有做任何更改
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#ffff00"
- android:orientation="vertical" >
- </LinearLayout>
java代码:
- public class Fragment2 extends Fragment {
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- View view=inflater.inflate(R.layout.layout2, container, false);
- return view;
- }
- }
第三个Fragment类:
XML代码:(layout3.xml)同样,原生代码,没做任何更改
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#ff00ff"
- android:orientation="vertical" >
- </LinearLayout>
java代码:
- public class Fragment3 extends Fragment {
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- View view=inflater.inflate(R.layout.layout3, container, false);
- return view;
- }
- }
3、主activity实现
核心代码:
- public class MainActivity extends FragmentActivity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- //构造适配器
- List<Fragment> fragments=new ArrayList<Fragment>();
- fragments.add(new Fragment1());
- fragments.add(new Fragment2());
- fragments.add(new Fragment3());
- FragAdapter adapter = new FragAdapter(getSupportFragmentManager(), fragments);
- //设定适配器
- ViewPager vp = (ViewPager)findViewById(R.id.viewpager);
- vp.setAdapter(adapter);
- }
- }
首先有一个最值得注意的地方:Activity派生自FragmentActivity,其实这是有关Fragment的基础知识,只有FragmentActivity才能内嵌fragment页面,普通Activity是不行的。
这段代码主要分为两步,第一步:构造适配器;第二步:设定适配器。
先看构造适配器的过程:
- //构造适配器
- List<Fragment> fragments=new ArrayList<Fragment>();
- fragments.add(new Fragment1());
- fragments.add(new Fragment2());
- fragments.add(new Fragment3());
- FragAdapter adapter = new FragAdapter(getSupportFragmentManager(), fragments);
构造一个fragment列表,然后将上面的三个Fragment类对应的实例添加进去,最后生成FragAdapter实例。
至于第二步,设定适配器,没什么好讲的。
4、可能出现的问题
问题:在MainActivity中,当写到这句:fragments.add(new Fragment1()); 向Fragment列表中添加Fragement对象实例时,会提示“无法将Fragment1()转换为fragment”
解决办法 :这是因为导入包不一致,一般的问题在于:在Fragment1中导入的是android.app.Fragment, 而在这里导入类确是:android.support.v4.app.Fragment,包不同当然无法转换,统一导入为android.support.v4.app.Fragment之后就正常了.参考文章《android之cannot convert from Fragment1 to Fragment》
源码下载地址:http://download.csdn.net/detail/harvic880925/7777849
请大家尊重原创者版权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/38660861 不胜感激!
ViewPager 详解(五)-----使用Fragment实现ViewPager滑动的更多相关文章
- ViewPager 详解(四)----自主实现滑动指示条
前言:前面我们用了三篇的时间讲述了有关ViewPager的基础知识,到这篇就要进入点实际的了.在第三篇<ViewPager 详解(三)---PagerTabStrip与PagerTitleStr ...
- Android Fragment详解(五):Fragment与Activity通讯
与activity通讯 尽管fragment的实现是独立于activity的,可以被用于多个activity,但是每个activity所包含的是同一个fragment的不同的实例. Fragment可 ...
- ViewPager 详解(二)---详解四大函数
前言:上篇中我们讲解了如何快速实现了一个滑动页面,但问题在于,PageAdapter必须要重写的四个函数,它们都各有什么意义,在上节的函数内部为什么要这么实现,下面我们就结合Android的API说明 ...
- ViewPager 详解(三)---PagerTabStrip与PagerTitleStrip添加标题栏的异同
前言:在前两篇文章中,我们讲解了滑动页面的的实现方法与四大函数的意义,但有时,仅仅实现页面滑动是不够的,还要有标题栏才会显得更友好.所以在这篇文章中,我将会向大家展示在Android.support. ...
- ViewPager 详解(一)---基本入门
前言:这两天研究研究ViewPager滚动功能,现在很多的app都有用到这个功能,我们的大虾米也有这个模块.要研究就彻底的研究研究,我从不满足于一个功能只是简单的应用,要学就学的彻底,所以我打算将Vi ...
- [转]ViewPager 详解(三)---PagerTabStrip与PagerTitleStrip添加标题栏的异同
目录(?)[-] 一PagerTitleStrip Class Overview XML布局文件 重写适配器的getPageTitle函数 变量 初始化 重写CharSequence getPag ...
- Fragment详解之三——管理Fragment(1)
相关文章: 1.<Fragment详解之一--概述>2.<Fragment详解之二--基本使用方法>3.<Fragment详解之三--管理Fragment(1)>4 ...
- .NET DLL 保护措施详解(五)常规条件下的破解
为了证实在常规手段破解下能有效保护程序核心功能(演示版本对AES加解密算法及数据库的密钥(一段字符串)进行了保护),特对此DLL保护思路进行相应的测试,包含了反编译及反射测试,看是否能得到AES加解密 ...
- 转:Windows下的PHP开发环境搭建——PHP线程安全与非线程安全、Apache版本选择,及详解五种运行模式。
原文来自于:http://www.ituring.com.cn/article/128439 Windows下的PHP开发环境搭建——PHP线程安全与非线程安全.Apache版本选择,及详解五种运行模 ...
随机推荐
- C++ Built-In Array 的语义
C++ 编译花了大量精力使得class和原始类(primitive types)的用法一致.比如array的应用: A a[100]:// A is class int b[100]: 虽然a是用户定 ...
- 小波 mallat 算法
算法要求:输入序列是大于滤波器长度的偶数列 确实可以通过编程的手段使算法适合所有的情况,但本文章的目的是展示mallat算法的过程,所以就一切从简了 // Mallat.cpp : Defines t ...
- sae crop 文档
原文是google缓存:http://webcache.googleusercontent.com/search?q=cache:MD_FP-G6RI8J:sae.sina.com.cn/%3Fm%3 ...
- underscorejs-where学习
2.7 where 2.7.1 语法: _.where(list, predicate) 2.7.2 说明: 对list集合的每个对象依次与predicate对象进行匹配,返回一个数组(数组为匹配成功 ...
- js 求两个日期之间相差天数
//求两个日期之间的相差天数 function daysBetween(DateOne, DateTwo) { var OneMonth = DateOne.substring(5, DateOne. ...
- HTml <meta>标签的使用(重要)
<meta> 元素可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词. 1.设置网页字符编码 <meta http-equiv=&q ...
- 如何在django中使用多个数据库
http://blog.chinaunix.net/uid-16728139-id-4364343.html
- ppt怎么换背景图片|PPT换背景设置方法
PPT怎么换背景?PPT背景可谓是PPT幻灯片的灵魂,优美绚丽的PPT背景能为自己做的PPT幻灯片锦上添花.今天,格子啦小编就教大家PPT换背景的方法,让你不再羡慕别人所做PPT的美丽背景,也可以自己 ...
- iOS开发网络篇—XML数据的解析
iOS开发网络篇—XML数据的解析 iOS开发网络篇—XML介绍 一.XML简单介绍 XML:全称是Extensible Markup Language,译作“可扩展标记语言” 跟JSON一样,也是 ...
- xcode 发展史 及 做iOS 必须知道的小知识
Xcode 3.0 是开发人员建立 Mac OS X 应用程序的最快捷方式,也是利用新的苹果电脑公司技术的最简单的途径.Xcode 3.0 将Mac OS X的轻松使用,UNIX 能量以及高性能的开发 ...