第 11 章 使用 ViewPager
請參考教材,全面理解和完成本章節內容... ...
復制工程ch10,將工程目錄改名為ch11。
本章,我們將創建一個新的activity,用以托管CrimeFragment。新建activity的布局將由一個ViewPager實例組成。為UI添加ViewPager后,用戶可滑動屏幕,切換查看不同列表項的明細頁面,如圖11-1所示。
圖11-1 劃屏顯示Crime明細內容
圖11-2為升級后的CriminalIntent應用對象圖解。圖中可以看到,名為CrimePagerActivity的新建activity將取代CrimeActivity。其布局將由一個ViewPager組成。
圖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)
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)
創建資源ID后,即可創建并顯示ViewPager。在CrimePagerActivity.java中,實例化ViewPager類,并將其設置為內容視圖,如代碼清單11-3所示。代碼清單11-3 以代碼的方式創建內容視圖(CrimePagerActivity.java)
ViewPager類來自于支持庫。與Fragment類不同,ViewPager只存在于支持庫中。而且,可以預見,即使在SDK的后續版本中,并不存在"標準的"ViewPager類。
11.1.2ViewPager與PagerAdapter
ViewPager在某種程度上有點類似于AdapterView(ListView的超類)。AdapterView需借助于Adapter才能提供視圖。同樣地,ViewPager也需要PagerAdapter的支持。
不過,相較于AdapterView與Adapter間的協同工作,ViewPager與PagerAdapte間的配合要復雜的多。幸運的是,可使用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)
?
下面來逐行解讀新增代碼。第一行,我們從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)
除此之外,還需在manifest配置文件中添加CrimePagerActivity,使得操作系統能夠啟動它,如代碼清單11-6所示。打開AndroidManifest.xml,添加CrimePagerActivity聲明,同時刪除不再使用的CrimeActivity聲明。
代碼清單11-6 添加CrimePagerActivity到manifest配置文件(AndroidManifest.xml)
最后,為保持項目的整潔性,從工程中刪除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)
運行CriminalIntent應用。選擇任意列表項,其對應的Crime明細內容應該能夠顯示了。
注:我無法用Android Studio 實現以下內容
為完善明細頁面的顯示,還可將顯示在操作欄(舊版本設備上叫標題欄)上的activity標題替換成當前Crime的標題。可通過實現ViewPager.OnPageChangeListener接口,完成此項優化,如代碼清單11-8所示。(setOnPageChangeListener 已經作廢)
代碼清單11-8 添加OnPageChangeListener監聽器(CrimePagerActivity.java)
轉載于:https://www.cnblogs.com/jlxuqiang/p/4755951.html
總結
以上是生活随笔為你收集整理的第 11 章 使用 ViewPager的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MockupBuilder
- 下一篇: 基于 Token 的身份验证方法