zoukankan      html  css  js  c++  java
  • 第 11 章 使用 ViewPager

    请参考教材,全面理解和完成本章节内容... ...

    复制工程ch10,将工程目录改名为ch11。

    本章,我们将创建一个新的activity,用以托管CrimeFragment。新建activity的布局将由一个ViewPager实例组成。为UI添加ViewPager后,用户可滑动屏幕,切换查看不同列表项的明细页面,如图11-1所示。

    image

    图11-1 划屏显示Crime明细内容

    图11-2为升级后的CriminalIntent应用对象图解。图中可以看到,名为CrimePagerActivity的新建activity将取代CrimeActivity。其布局将由一个ViewPager组成。

    image

    图11-2 CrimePagerActivity的布局示意图

    如图所示,无需改变CriminalIntent应用的其他部分,我们只要创建虚线框中的对象即可实现划屏切换Crime明细页面。特别要说的是,由于上一章中确保CrimeFragment通用独立性的努力,这里就不用再考虑对CrimeFragment类进行调整了。

    本章,我们将完成以下任务:

    • 创建CrimePagerActivity类;
    • 定义包含ViewPager的视图层级结构;
    • 在CrimePagerActivity类中关联使用ViewPager及其adapter;
    • 修改CrimeListFragment.onListItemClick(...)方法,启动CrimePagerActivity,而非CrimeActivity。

    11.1 创建 CrimePagerActivity

    CrimePagerActivity设计为FragmentActivity类的子类。在CriminalIntent应用中,其任务是创建并管理ViewPager

    FragmentActivity为超类,创建一个名为CrimePagerActivity的新类。覆盖onCreate(Bundle)方法,并在其中调用超类版本的对应方法。再添加一个mViewPager变量,忽略变量未曾使用的提示,稍后将创建ViewPager的实例,如代码清单11-1所示。

    代码清单11-1 创建ViewPager(CrimePagerActivity.java)

    image

    11.1.1 以代码的方式定义并产生布局

    在本书的其余章节中,我们都是在XML布局文件中定义视图布局的。通常来说,这是种好方法。但Android并没有硬性规定我们必须使用此种方法。本章中的视图层级结构很简单,仅有一个视图。因此,我们来学习以代码的方式定义视图层级结构。既然只有一个视图,此项任务处理起来并不复杂。

    以代码的方式创建视图并不神奇,简单的说就是调用视图的构造方法而已。不幸的是,我们还无法完全弃用XML文件。因为某些构建块(component)依然需要资源ID。ViewPager就是这样的一种构建块。FragmentManager要求任何用作fragment容器的视图都必须具有资源ID。ViewPager是一个fragment容器,因此,必须赋予其资源ID。

    以代码的方式创建视图,应完成以下任务项:

    • 为ViewPager创建资源ID;
    • 创建ViewPager实例并赋值给mViewPager;
    • 赋值资源ID给ViewPager,并对其进行配置;
    • 设置ViewPager为activity的内容视图。

    独立资源ID

    定义独立资源ID与定义字符串资源ID并没有什么不同:在res/values目录下的XML文件中创建一个项目元素。创建一个名为res/values/ids.xml的Android XML资源文件,用以存储资源ID,并 在其中新增一个名为viewPager的ID,如代码清单11-2所示。

    代码清单11-2 创建独立资源ID(res/values/ids.xml)

    image
    创建资源ID后,即可创建并显示ViewPager。在CrimePagerActivity.java中,实例化ViewPager类,并将其设置为内容视图,如代码清单11-3所示。

    代码清单11-3 以代码的方式创建内容视图(CrimePagerActivity.java)

    image

    ViewPager类来自于支持库。与Fragment类不同,ViewPager只存在于支持库中。而且,可以预见,即使在SDK的后续版本中,并不存在"标准的"ViewPager类。

    11.1.2ViewPagerPagerAdapter

    ViewPager在某种程度上有点类似于AdapterViewListView的超类)。AdapterView需借助于Adapter才能提供视图。同样地,ViewPager也需要PagerAdapter的支持。

    不过,相较于AdapterViewAdapter间的协同工作,ViewPagerPagerAdapte间的配合要复杂的多。幸运的是,可使用PagerAdapte的子类——FragmentStatePagerAdapter,来处理许多细节问题。

    FragmentStatePagerAdapter对二者间的配合支持实际归结为两个简单方法的使用,即getCount()getItem(int)。调用getItem(int)方法获取crime数组指定位置的Crime时,它会返回一个已配置的用于显示指定位置crime信息的CrimeFragment

    CrimePagerActivity中,添加代码清单11-4所示代码,设置ViewPager的pager adapter,并实现它的getCount()getItem(int)方法。

    代码清单11-4 设置pager adapter(CrimePagerActivity.java)

    image

    下面来逐行解读新增代码。第一行,我们从CrimeLab中(crime的ArrayList)获取数据集,然后获取activity的FragmentManager实例。

    接下来,设置adapter为FragmentStatePagerAdapter的一个匿名实例。创建FragmentStatePagerAdapter实例,还需传入FragmentManager给它的构造方法。如前所述,FragmentStatePagerAdapter是我们的代理,负责管理与ViewPager的对话并协同工作。代理需首先将getItem(int)方法返回的fragment添加给activity,然后才能使用fragment完成自己的工作。这也就是创建代理实例时,需要FragmentManager的原因所在。

    (代理究竟做了哪些工作呢?简单来说,就是将返回的fragment添加给托管activity,并帮助Viewpager找到fragment的视图并一一对应。可参看本章末的深入学习部分了解更多详细内容。)

    Pager adapter的两个方法简单直接。getCount()方法用来返回数组列表中包含的列表项数目。getItem(int)方法非常神奇。它首先获取了数据集中指定位置的Crime实例,然后利用该Crime实例的ID创建并返回一个有效配置的CrimeFragment

    11.1.3 整合配置并使用CrimePagerActivity

    现在,废弃使用CrimeActivity,我们来配置使用CrimePagerActivity

    首先对CrimeListFragment进行调整,使得用户单击某个列表项时,CrimeListFragment启动的是CrimePagerActivity实例,而非原来的CrimeActivity

    返回至CrimeListFragment.java文件,修改onListItemClick(...)方法,启动CrimePagerActivity,如代码清单11-5所示。

    代码清单11-5 配置启动CrimePagerActivity(CrimeListFragment.java)

    image

    除此之外,还需在manifest配置文件中添加CrimePagerActivity,使得操作系统能够启动它,如代码清单11-6所示。打开AndroidManifest.xml,添加CrimePagerActivity声明,同时删除不再使用的CrimeActivity声明。

    代码清单11-6 添加CrimePagerActivity到manifest配置文件(AndroidManifest.xml)

    image

    最后,为保持项目的整洁性,从工程中删除CrimeActivity.java文件。

    运行CriminalIntent应用。点击Crime #0查看其明细内容。然后划屏浏览其他crime明细内容。可以看到,整个页面切换过程流畅顺滑,数据加载毫无延迟。ViewPager默认加载当前屏幕上的列表项,以及左右相邻页面的数据,从而实现页面滑动的快速切换。可通过调用setOffscreenPageLimit(int)方法,定制预加载相邻页面的数目。

    注意,目前ViewPager还不够完美。单击后退键返回列表项界面,点选其他Crime列表项,但屏幕上显示的却仍是第一个Crime列表项的内容,而非当前点选的列表项。

    ViewPager默认只显示PageAdapter中的第一个列表项。可设置ViewPager当前要显示的列表项为Crime数组中指定位置的列表项,从而实现所选列表项的正确显示。

    CrimePagerActivity.onCreate(...)方法的末尾,循环检查crime的ID,找到所选crime在数组中的索引位置。如Crime实例的mId与intent extra的crimeId相匹配,则将当前要显示的列表项设置为Crime在数组中的索引位置,如代码清单11-7所示。

    代码清单11-7 设置初始分页显示项(CrimePagerActivity.java)

    image

    运行CriminalIntent应用。选择任意列表项,其对应的Crime明细内容应该能够显示了。

    注:我无法用Android Studio 实现以下内容

    为完善明细页面的显示,还可将显示在操作栏(旧版本设备上叫标题栏)上的activity标题替换成当前Crime的标题。可通过实现ViewPager.OnPageChangeListener接口,完成此项优化,如代码清单11-8所示。setOnPageChangeListener 已经作废)

    代码清单11-8 添加OnPageChangeListener监听器(CrimePagerActivity.java)

    image

  • 相关阅读:
    linux基础学习6
    Linux基础学习5
    Linux基础学习4
    Linux基础学习3
    Linux基础学习2
    ASP.NET MVC学习——控制器传递数据到view的简单案例
    转载:URL链接中的不同用处
    MVC学习的心路历程
    45道SQL数据题详细超基础解析
    结束基础,开始MVC之旅!
  • 原文地址:https://www.cnblogs.com/jlxuqiang/p/4755951.html
Copyright © 2011-2022 走看看