BaseActivity与BaseFragment的封装
這篇博客主要是從BaseActivity與BaseFragment的封裝開始,總結我們在實戰開發中關于Fragment的注意事項以及心得體會。
先看以下效果圖:
這里模擬的是用戶登錄模塊,你可能會說,很普通的效果嘛,這有啥。嘿嘿,那我要告訴你的是,這么多模塊僅僅由兩個Activity構成的。等你從頭到尾看完這篇博客,你就會驚嘆其中的奧秘了。廢話不多說,開始。
本案例屬于多模塊Activity+多Fragment,下面簡單介紹下概念。
多模塊Activity+多Fragment 是開發APP非常適合的架構,相對于多Activity,這種架構APP占用內存降低,性能提升;相對于單Activity+多Fragment,這種開發起來邏輯相對簡單,不容易出錯。
對于多模塊Activity+多Fragment,這里有兩個概念需要我們了解一下:
- 同級式Fragment: 比如QQ的主界面,消息,聯系人,動態,這三個Fragment就屬于同級關系,我們平時項目中主界面的Fragment也是屬于同級Fragment
- 流程式Fragment:比如我這個示例Demo,可以理解為用戶賬戶流程,可以包括:登錄/注冊模塊—-忘記/找回密碼模塊—-用戶協議模塊,這些Fragent就是屬于流程式Fragment
我的示例Demo使用的是流程式Fragment,結合今天的主題—-BaseActivity與BaseFragment的封裝,我們一探究竟。
BaseActivity的封裝
首先看一下代碼:
兩個必須實現的抽象方法,獲取布局文件Layout的resource ID,獲取布局文件中Fragment的ID
添加fragment:開啟一個事物,替換了當前layout容器中的由getFragmentContentId()標識的fragment。通過調用 addToBackStack(String tag), replace事務被保存到back stack, 因此用戶可以回退事務,并通過按下BACK按鍵帶回前一個fragment,如果沒有調用 addToBackStack(String tag), 那么當事務提交后, 那個fragment會被銷毀,并且用戶不能導航回到它。其中參數tag將作為本次加入BackStack的Transaction的標志。commitAllowingStateLoss(),這種提交是允許發生異常時狀態值丟失的情況下也能正常提交事物
移除fragment:與addToBackStack()相對應的接口方法是popBackStack(),調用該方法后會將事務操作插入到FragmentManager的操作隊列,輪詢到該事務時開始執行。這里進行了一下判斷,獲取回退棧中所有事務數量,大于1的時候,執行回退操作,等于1的時候,代表當前Activity只剩下一個Fragment,直接finish()當前Activity即可
監聽返回鍵的返回事件,當事務數量等于1的時候,直接finish()
進一步封裝AppActivity
不過這樣的封裝是需要制定一個布局文件的,activity_base.xml布局文件代碼為:
BaseFragment的封裝
在APP運行在后臺的時候,系統資源緊張的時候會導致后臺的Activity被銷毀,可能會帶來一些問題,其中之一就是Fragment調用getActivity()的地方卻返回null,報了空指針異常。
解決辦法就是在Fragment基類里設置一個Activity mActivity的全局變量,在onAttach(Activity activity)里賦值,使用mActivity代替getActivity()。
封裝后的使用
BaseActivity與BaseFragment的封裝都已經完成,接下來就是具體在項目中的使用了,這里分兩種情況。
- 第一種情況:沒有參數的傳遞
示例Demo中的主界面MainActivity,可以看到代碼相當的精簡,對應的MainFragment代碼如下:
很簡單的業務邏輯,點擊第一個按鈕跳轉到LoginActivity,點擊第二個按鈕跳轉到注冊模塊,布局文件代碼就不貼了。
- 第二種情況:有參數的傳遞
可以看到,LoginActivity與之前不一樣的是,重寫了handleIntent()這個方法來獲取傳遞過來的數據,重要的一點,創建Fragment的時候傳遞了一個參數。 代碼很簡單,即通過Arguments傳遞參數。
給Fragment添加newInstance方法,將需要的參數傳入,設置到bundle中,然后setArguments(bundle),最后在onCreate中進行獲取。
這種使用arguments來創建Fragment的方法,強烈推薦使用:
這樣就完成了Fragment和Activity間的解耦,使用Fragment的一個很大的原因,就是為了復用。這一點在我主界面點擊第二個按鈕跳轉到注冊界面有所體現
對Fragment傳遞數據,建議使用setArguments(Bundle args),而后在onCreate中使用getArguments()取出,在 內存不足導致異常時,系統會幫你保存數據,不會造成數據的丟失。和Activity的Intent原理一致。
使用newInstance(參數) 創建Fragment對象,優點是調用者只需要關系傳遞的哪些數據,而無需關心傳遞數據的Key是什么。
其他界面大同小異,大家可以在此自由發揮。關于流程式Fragment,就先到這里,看看同級式Fragment應該注意的問題。
hide()與show()導致的Fragment重疊
同級式Fragment在內存不足導致的異常情況下,會出現重疊現象,處理方法是在基類的Activity中onSaveInstanceState()內保存當前所在Fragment的tag或者下標,在onCreate()是恢復的時候,隱藏其它Fragment。
假設我們存在三個同級Fragment,目前Fragment為ContactFragment,此時切換到后臺,由于內存因素導致Activity重建,我們就可以通過上述代碼解決Fragment重疊以及回到ContactFragment頁面。
當然要記得在onSaveInstanceState存儲下當前頁面信息
推薦閱讀
- Fragment全解析系列(一):那些年踩過的坑
- Fragment全解析系列(二):正確的使用姿勢
- Fragment之我的解決方案:Fragmentation
- Android Fragment 你應該知道的一切
參考鏈接
從BaseActivity與BaseFragment的封裝談起
總結
以上是生活随笔為你收集整理的BaseActivity与BaseFragment的封装的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android之数据库操作
- 下一篇: Redis配置文件常用配置消息解说--版