第 11 章 使用 ViewPager
請(qǐng)參考教材,全面理解和完成本章節(jié)內(nèi)容... ...
復(fù)制工程ch10,將工程目錄改名為ch11。
本章,我們將創(chuàng)建一個(gè)新的activity,用以托管CrimeFragment。新建activity的布局將由一個(gè)ViewPager實(shí)例組成。為UI添加ViewPager后,用戶可滑動(dòng)屏幕,切換查看不同列表項(xiàng)的明細(xì)頁(yè)面,如圖11-1所示。
圖11-1 劃屏顯示Crime明細(xì)內(nèi)容
圖11-2為升級(jí)后的CriminalIntent應(yīng)用對(duì)象圖解。圖中可以看到,名為CrimePagerActivity的新建activity將取代CrimeActivity。其布局將由一個(gè)ViewPager組成。
圖11-2 CrimePagerActivity的布局示意圖
如圖所示,無(wú)需改變CriminalIntent應(yīng)用的其他部分,我們只要?jiǎng)?chuàng)建虛線框中的對(duì)象即可實(shí)現(xiàn)劃屏切換Crime明細(xì)頁(yè)面。特別要說(shuō)的是,由于上一章中確保CrimeFragment通用獨(dú)立性的努力,這里就不用再考慮對(duì)CrimeFragment類進(jìn)行調(diào)整了。
本章,我們將完成以下任務(wù):
- 創(chuàng)建CrimePagerActivity類;
- 定義包含ViewPager的視圖層級(jí)結(jié)構(gòu);
- 在CrimePagerActivity類中關(guān)聯(lián)使用ViewPager及其adapter;
- 修改CrimeListFragment.onListItemClick(...)方法,啟動(dòng)CrimePagerActivity,而非CrimeActivity。
11.1 創(chuàng)建 CrimePagerActivity
CrimePagerActivity設(shè)計(jì)為FragmentActivity類的子類。在CriminalIntent應(yīng)用中,其任務(wù)是創(chuàng)建并管理ViewPager。
以FragmentActivity為超類,創(chuàng)建一個(gè)名為CrimePagerActivity的新類。覆蓋onCreate(Bundle)方法,并在其中調(diào)用超類版本的對(duì)應(yīng)方法。再添加一個(gè)mViewPager變量,忽略變量未曾使用的提示,稍后將創(chuàng)建ViewPager的實(shí)例,如代碼清單11-1所示。
代碼清單11-1 創(chuàng)建ViewPager(CrimePagerActivity.java)
11.1.1 以代碼的方式定義并產(chǎn)生布局
在本書的其余章節(jié)中,我們都是在XML布局文件中定義視圖布局的。通常來(lái)說(shuō),這是種好方法。但Android并沒(méi)有硬性規(guī)定我們必須使用此種方法。本章中的視圖層級(jí)結(jié)構(gòu)很簡(jiǎn)單,僅有一個(gè)視圖。因此,我們來(lái)學(xué)習(xí)以代碼的方式定義視圖層級(jí)結(jié)構(gòu)。既然只有一個(gè)視圖,此項(xiàng)任務(wù)處理起來(lái)并不復(fù)雜。
以代碼的方式創(chuàng)建視圖并不神奇,簡(jiǎn)單的說(shuō)就是調(diào)用視圖的構(gòu)造方法而已。不幸的是,我們還無(wú)法完全棄用XML文件。因?yàn)槟承?gòu)建塊(component)依然需要資源ID。ViewPager就是這樣的一種構(gòu)建塊。FragmentManager要求任何用作fragment容器的視圖都必須具有資源ID。ViewPager是一個(gè)fragment容器,因此,必須賦予其資源ID。
以代碼的方式創(chuàng)建視圖,應(yīng)完成以下任務(wù)項(xiàng):
- 為ViewPager創(chuàng)建資源ID;
- 創(chuàng)建ViewPager實(shí)例并賦值給mViewPager;
- 賦值資源ID給ViewPager,并對(duì)其進(jìn)行配置;
- 設(shè)置ViewPager為activity的內(nèi)容視圖。
獨(dú)立資源ID
定義獨(dú)立資源ID與定義字符串資源ID并沒(méi)有什么不同:在res/values目錄下的XML文件中創(chuàng)建一個(gè)項(xiàng)目元素。創(chuàng)建一個(gè)名為res/values/ids.xml的Android XML資源文件,用以存儲(chǔ)資源ID,并 在其中新增一個(gè)名為viewPager的ID,如代碼清單11-2所示。
代碼清單11-2 創(chuàng)建獨(dú)立資源ID(res/values/ids.xml)
創(chuàng)建資源ID后,即可創(chuàng)建并顯示ViewPager。在CrimePagerActivity.java中,實(shí)例化ViewPager類,并將其設(shè)置為內(nèi)容視圖,如代碼清單11-3所示。代碼清單11-3 以代碼的方式創(chuàng)建內(nèi)容視圖(CrimePagerActivity.java)
ViewPager類來(lái)自于支持庫(kù)。與Fragment類不同,ViewPager只存在于支持庫(kù)中。而且,可以預(yù)見,即使在SDK的后續(xù)版本中,并不存在"標(biāo)準(zhǔn)的"ViewPager類。
11.1.2ViewPager與PagerAdapter
ViewPager在某種程度上有點(diǎn)類似于AdapterView(ListView的超類)。AdapterView需借助于Adapter才能提供視圖。同樣地,ViewPager也需要PagerAdapter的支持。
不過(guò),相較于AdapterView與Adapter間的協(xié)同工作,ViewPager與PagerAdapte間的配合要復(fù)雜的多。幸運(yùn)的是,可使用PagerAdapte的子類——FragmentStatePagerAdapter,來(lái)處理許多細(xì)節(jié)問(wèn)題。
FragmentStatePagerAdapter對(duì)二者間的配合支持實(shí)際歸結(jié)為兩個(gè)簡(jiǎn)單方法的使用,即getCount()和getItem(int)。調(diào)用getItem(int)方法獲取crime數(shù)組指定位置的Crime時(shí),它會(huì)返回一個(gè)已配置的用于顯示指定位置crime信息的CrimeFragment。
在CrimePagerActivity中,添加代碼清單11-4所示代碼,設(shè)置ViewPager的pager adapter,并實(shí)現(xiàn)它的getCount()和getItem(int)方法。
代碼清單11-4 設(shè)置pager adapter(CrimePagerActivity.java)
?
下面來(lái)逐行解讀新增代碼。第一行,我們從CrimeLab中(crime的ArrayList)獲取數(shù)據(jù)集,然后獲取activity的FragmentManager實(shí)例。
接下來(lái),設(shè)置adapter為FragmentStatePagerAdapter的一個(gè)匿名實(shí)例。創(chuàng)建FragmentStatePagerAdapter實(shí)例,還需傳入FragmentManager給它的構(gòu)造方法。如前所述,FragmentStatePagerAdapter是我們的代理,負(fù)責(zé)管理與ViewPager的對(duì)話并協(xié)同工作。代理需首先將getItem(int)方法返回的fragment添加給activity,然后才能使用fragment完成自己的工作。這也就是創(chuàng)建代理實(shí)例時(shí),需要FragmentManager的原因所在。
(代理究竟做了哪些工作呢?簡(jiǎn)單來(lái)說(shuō),就是將返回的fragment添加給托管activity,并幫助Viewpager找到fragment的視圖并一一對(duì)應(yīng)。可參看本章末的深入學(xué)習(xí)部分了解更多詳細(xì)內(nèi)容。)
Pager adapter的兩個(gè)方法簡(jiǎn)單直接。getCount()方法用來(lái)返回?cái)?shù)組列表中包含的列表項(xiàng)數(shù)目。getItem(int)方法非常神奇。它首先獲取了數(shù)據(jù)集中指定位置的Crime實(shí)例,然后利用該Crime實(shí)例的ID創(chuàng)建并返回一個(gè)有效配置的CrimeFragment。
11.1.3 整合配置并使用CrimePagerActivity
現(xiàn)在,廢棄使用CrimeActivity,我們來(lái)配置使用CrimePagerActivity。
首先對(duì)CrimeListFragment進(jìn)行調(diào)整,使得用戶單擊某個(gè)列表項(xiàng)時(shí),CrimeListFragment啟動(dòng)的是CrimePagerActivity實(shí)例,而非原來(lái)的CrimeActivity。
返回至CrimeListFragment.java文件,修改onListItemClick(...)方法,啟動(dòng)CrimePagerActivity,如代碼清單11-5所示。
代碼清單11-5 配置啟動(dòng)CrimePagerActivity(CrimeListFragment.java)
除此之外,還需在manifest配置文件中添加CrimePagerActivity,使得操作系統(tǒng)能夠啟動(dòng)它,如代碼清單11-6所示。打開AndroidManifest.xml,添加CrimePagerActivity聲明,同時(shí)刪除不再使用的CrimeActivity聲明。
代碼清單11-6 添加CrimePagerActivity到manifest配置文件(AndroidManifest.xml)
最后,為保持項(xiàng)目的整潔性,從工程中刪除CrimeActivity.java文件。
運(yùn)行CriminalIntent應(yīng)用。點(diǎn)擊Crime #0查看其明細(xì)內(nèi)容。然后劃屏瀏覽其他crime明細(xì)內(nèi)容。可以看到,整個(gè)頁(yè)面切換過(guò)程流暢順滑,數(shù)據(jù)加載毫無(wú)延遲。ViewPager默認(rèn)加載當(dāng)前屏幕上的列表項(xiàng),以及左右相鄰頁(yè)面的數(shù)據(jù),從而實(shí)現(xiàn)頁(yè)面滑動(dòng)的快速切換。可通過(guò)調(diào)用setOffscreenPageLimit(int)方法,定制預(yù)加載相鄰頁(yè)面的數(shù)目。
注意,目前ViewPager還不夠完美。單擊后退鍵返回列表項(xiàng)界面,點(diǎn)選其他Crime列表項(xiàng),但屏幕上顯示的卻仍是第一個(gè)Crime列表項(xiàng)的內(nèi)容,而非當(dāng)前點(diǎn)選的列表項(xiàng)。
ViewPager默認(rèn)只顯示PageAdapter中的第一個(gè)列表項(xiàng)。可設(shè)置ViewPager當(dāng)前要顯示的列表項(xiàng)為Crime數(shù)組中指定位置的列表項(xiàng),從而實(shí)現(xiàn)所選列表項(xiàng)的正確顯示。
在CrimePagerActivity.onCreate(...)方法的末尾,循環(huán)檢查crime的ID,找到所選crime在數(shù)組中的索引位置。如Crime實(shí)例的mId與intent extra的crimeId相匹配,則將當(dāng)前要顯示的列表項(xiàng)設(shè)置為Crime在數(shù)組中的索引位置,如代碼清單11-7所示。
代碼清單11-7 設(shè)置初始分頁(yè)顯示項(xiàng)(CrimePagerActivity.java)
運(yùn)行CriminalIntent應(yīng)用。選擇任意列表項(xiàng),其對(duì)應(yīng)的Crime明細(xì)內(nèi)容應(yīng)該能夠顯示了。
注:我無(wú)法用Android Studio 實(shí)現(xiàn)以下內(nèi)容
為完善明細(xì)頁(yè)面的顯示,還可將顯示在操作欄(舊版本設(shè)備上叫標(biāo)題欄)上的activity標(biāo)題替換成當(dāng)前Crime的標(biāo)題。可通過(guò)實(shí)現(xiàn)ViewPager.OnPageChangeListener接口,完成此項(xiàng)優(yōu)化,如代碼清單11-8所示。(setOnPageChangeListener 已經(jīng)作廢)
代碼清單11-8 添加OnPageChangeListener監(jiān)聽器(CrimePagerActivity.java)
轉(zhuǎn)載于:https://www.cnblogs.com/jlxuqiang/p/4755951.html
總結(jié)
以上是生活随笔為你收集整理的第 11 章 使用 ViewPager的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: MockupBuilder
- 下一篇: 基于 Token 的身份验证方法