ViewPage+Fragment的使用用法
一、概述
从前面几篇文章,我们知道,实现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集。(没理解什么意思)
对于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》
转载出处: ViewPager 详解(五)-----使用Fragment实现ViewPager滑动
ViewPage+Fragment的使用用法的更多相关文章
- Android Studio精彩案例(三)《模仿微信ViewPage+Fragment实现方式二》
转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 写在前面的话:此专栏是博主在工作之余所写,每一篇文章尽可能写的思路清晰一些,属于博主的"精华"部分,不同于以往专栏 ...
- Android典型界面设计——ViewPage+Fragment实现区域顶部tab滑动切换
一.问题描写叙述 本系列将结合案例应用,陆续向大家介绍一些Android典型界面的设计,首先说说tab导航,导航分为一层和两层(底部区块+区域内头部导航).主要实现方案有RadioGroup+View ...
- Android之取消ViewPage+Fragment的预加载
用过ViewPage+Fragment组合的童鞋自然知道这个问题,没有遇到的同学祝愿你们永远不会遇到,呵呵.直接上关键代码 注释:setUserVisibleHint每次fragment显示与隐藏都会 ...
- Fragment的基本用法
一.Fragment主要用到的API: 1.Fragment 类-----用来创建碎片 2.FragmentManager 类 ----为管理Activity中Fragment,用于Activity与 ...
- android关于fragment的构造函数用法建议
错误信息 Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArgumen ...
- VIewPage+Fragment
效果图: 代码 public class NewOrderListFargmentActivity extends BaseActivity implements OnClickListener { ...
- ViewPage+Fragment(仿微信切换带通知)
第一步 : 布局文件 activity_main.xml <?xml version="1.0" encoding="utf-8"?> <Li ...
- ViewPage + Fragment 防止Fragment 重复加载问题
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanc ...
- 【Android自学日记】【转】Android Fragment 真正的完全解析(下)
上篇博客中已经介绍了Fragment产生原因,以及一些基本的用法和各种API,如果你还不了解,请看:Android Fragment 真正的完全解析(上). 本篇将介绍上篇博客提到的:如何管理Frag ...
随机推荐
- 如何使用Swagger为.NET Core 3.0应用添加JWT授权说明文档
简介 本教程采用WHY-WHAT-HOW黄金圈思维模式编写,黄金圈法则强调的是从WHY为什么学,到WHAT学到什么,再到HOW如何学.从模糊到清晰的学习模式.大家的时间都很宝贵,我们做事前先想清楚为什 ...
- 现在Java 桌面应用程序能做到什么程度(Spring Boot+JavaFX2开发)
Spring Boot - JavaFX 2.0应用 很多人对Java开发native程序第一反应还停留在暗灰色单一风格的Java GUI界面,开发方式还停留在AWT或者Swing.本文主要基于Spr ...
- 解决移动端touch事件与click冲突的问题
最简单的办法,就只绑定一个事件不就行了: 第二种,我觉得和第一种也没啥区别.. const Button = document.getElementById("targetButton&qu ...
- 以Mnist为例从头开始自己建立数据集,搭建resnet34,识别Mnist
写在前面: 本人小白研一,刚开始学习深度学习,将自己的第一个实验过程总结下来,看了很多的大牛的博客,在下面的程序中也参考了很多大牛的博客.在刚开始入门的学习的时候,直接编写程序下载数据集,但是后来觉得 ...
- 第三十二章 System V信号量(三)
n哲学家进餐问题描述有五个哲学家,他们的生活方式是交替地进行思考和进餐,n哲学家们共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子,n平时哲学家进行思考,饥饿时便试图取其左.右最靠近 ...
- Linux中的快捷方式
history 显示命令历史列表 ↑(Ctrl+p) 显示上一条命令 ↓(Ctrl+n) 显示下一条命令 !num 执行命令历史列表的第num条命令 !! 执行上一条命令 !?string? 执行含有 ...
- 基础练习1——ls的实现与递归
学习贵在坚持,兜兜转转,发现还是从基础做起吧,打好基础,才会长期的坚持下去... 第一个练习:shell命令 “ls"的实现与递归 1.简介:ls 的作用是列举当前目录下所有的目录和文件. ...
- SpringBoot系列:Spring Boot集成定时任务Quartz
一.关于Quartz Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用.在java企业级应用中,Q ...
- 一道国外前端面试题引发的Coding...
刚刚看到CSDN微信公众号一篇文章,关于国外程序员面试前端遇到的一道测试题,有点意思,遂写了下代码,并记录一下~ 题目是这样的: ['Tokyo', 'London', 'Rome', 'Donlon ...
- [Java]Java类和对象内存分配详解
描述 代码说明: 一.当Person p1 = new Person();第一次被调用时需要做两件事: 1.先判断类加载器是否加载过Person类,如果没有则加载到Person类型到方法区 2.在堆中 ...