Fragment系列文章:
一、Fragment全解析系列(一):那些年踩過的坑
二、Fragment全解析系列(二):正確的使用姿式
三、Fragment之個人解決方案:Fragmentationjava
若是你通讀了本系列的前兩篇,我相信你能夠寫出大部分場景都能正常運行的Fragment了。若是你想了解更多,那麼你能夠看看我封裝的這個庫:Fragmentation。
本篇主要介紹這個庫,解決了一些BUG,使用簡單,提供實時查看棧視圖等實用功能。git
源碼地址:Github,歡迎Fork,提Issues 。github
Demo網盤下載
Demo演示:單Activity+多Fragment架構
爲"單Activity + 多Fragment的架構","多模塊Activity + 多Fragment的架構"而生,幫你簡化使用過程,修復了官方Fragment庫存在的一些BUG。app
一、爲重度使用Fragment而生
二、提供了方便的管理Fragment的方法
三、有效解決Fragment重疊問題
四、實時查看Fragment的(包括嵌套Fragment)棧視圖,方便Fragment嵌套時的調試
五、增長啓動模式、startForResult等相似Activity方法
六、修復官方庫裏pop(tag/id)出棧多個Fragment時的一些BUG
七、完美解決進出棧動畫的一些BUG,更自由的管理Fragment的動畫ide
一、項目下app的build.gradle中依賴:gradle
compile 'me.yokeyword:fragmentation:0.3.0' // appcompat v7包也是必須的
二、Activity繼承SupportActivity:動畫
public class MainActivity extends SupportActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(...); if (savedInstanceState == null) { start(HomeFragment.newInstance()); } } /** * 設置Container的id,必須實現 */ @Override public int setContainerId() { return R.id.fl_container; } /** * 設置全局動畫,在SupportFragment能夠自由更改其動畫 */ @Override protected FragmentAnimator onCreateFragmentAnimator() { // 默認豎向(和安卓5.0以上的動畫相同) return super.onCreateFragmentAnimator(); // 設置橫向(和安卓4.x動畫相同) // return new DefaultHorizontalAnimator(); // 設置自定義動畫 // return new FragmentAnimator(enter,exit,popEnter,popExit); }
三、Fragment繼承SupportFragmentui
SupportActivity
打開 棧視圖 的提示框,在複雜嵌套的時候,能夠經過這個來清洗的理清不一樣階級的棧視圖。spa
// 彈出 棧視圖 提示框 showFragmentStackHierarchyView();
除此以外包含大部分SupportFragment的方法,請自行查看。
SupportFragment
一、啓動相關:
// 啓動新的Fragment start(SupportFragment fragment) // 以某種啓動模式,啓動新的Fragment start(SupportFragment fragment, int launchMode) // 啓動新的Fragment,並能接收到新Fragment的數據返回 startForResult(SupportFragment fragment,int requestCode) // 啓動目標Fragment,並關閉當前Fragment startWithFinish(SupportFragment fragment)
二、關閉Fragment:
// 關閉當前Fragment pop(); // 關閉某一個Fragment棧內之上的Fragments popTo(Class fragmentClass, boolean includeSelf); // 若是想出棧後,緊接着開始.beginTransaction()開始一個事務,請使用下面的方法: // 在 第二篇 文章內的 Fragment事務部分的問題 有解釋緣由 popTo(Class fragmentClass, boolean includeSelf, Runnable afterTransaction)
三、在SupportFragment內,支持監聽返回按鈕事件:
@Override public boolean onBackPressedSupport() { // 返回false,則繼續傳遞返回事件; 返回true則不繼續傳遞 return false; }
四、 定義當前Fragment的動畫,複寫onCreateFragmentAnimation
方法:
@Override protected FragmentAnimator onCreateFragmentAnimation() { // 獲取在SupportActivity裏設置的全局動畫對象 FragmentAnimator fragmentAnimator = _mActivity.getFragmentAnimator(); fragmentAnimator.setEnter(0); fragmentAnimator.setExit(0); return fragmentAnimator; // 也能夠直接經過 // return new FragmentAnimator(enter,exit,popEnter,popExit)設置一個全新的動畫 }
五、獲取當前Activity/Fragment內棧頂(子)Fragment:
getTopFragment();
六、獲取棧內某個Fragment對象:
findFragment(Class fragmentClass);
// 獲取某個子Fragment對象 findChildFragment(Class fragmentClass);
更多
隱藏/顯示 輸入法:
// 隱藏軟鍵盤 通常用在onHiden裏 hideSoftInput(); // 顯示軟鍵盤 showSoftInput(View view);
下面是DetailFragment startForResult
ModifyTitleFragment的代碼:
DetailFragment.class裏:
startForResult(ModifyDetailFragment.newInstance(mTitle), REQ_CODE);
@Override public void onFragmentResult(int requestCode, int resultCode, Bundle data) { super.onFragmentResult(requestCode, resultCode, data); if (requestCode == REQ_CODE && resultCode == RESULT_OK ) { // 在此經過Bundle data 獲取返回的數據 } } ModifyTitleFragment.class裏: Bundle bundle = new Bundle(); bundle.putString("title", "xxxx"); setFramgentResult(RESULT_OK, bundle);
下面是以一個singleTask模式start
一個Fragment的標準代碼:
HomeFragment fragment = findFragment(HomeFragment.class);
if (fragment == null) { fragment = HomeFragment.newInstance(); }else{ Bundle newBundle = new Bundle(); // 傳遞的bundle數據,會調用目標Fragment的onNewBundle(Bundle newBundle)方法 fragment.putNewBundle(newBundle); } // homeFragment以SingleTask方式啓動 start(fragment, SupportFragment.SINGLETASK); // 在HomeFragment.class中: @Override protected void onNewBundle(Bundle newBundle){ // 在此能夠接收到數據 }
2個概念:
"同級"式:好比QQ的主界面,「消息」、「聯繫人」、「動態」,這3個Fragment屬於同級關係
「流程」式:好比登陸->註冊/忘記密碼->填寫信息->跳轉到主頁Activity
對於Activity內的「流程」式Fragments(好比登陸->註冊/忘記密碼->填寫信息->跳轉到主頁Activity),Fragmentation幫助你處理了棧內的恢復,保證Fragment不會重疊,你不須要再本身處理了。
可是若是你的Activity內的Fragments是「同級」的,那麼須要你複寫onHandleSaveInstanceState()
使用findFragmentByTag(tag)
或getFragments()
去恢復處理。
@Override protected void onHandleSaveInstancState(Bundle savedInstanceState) { // 複寫的時候 下面的super必定要刪掉 // super.onHandleSaveInstancState(savedInstanceState); // 在此處 經過findFragmentByTag或getFraments來恢復,詳情參考第二篇文章 }
而若是你有Fragment嵌套,那麼無論是「同級」式仍是「流程」式,你都須要本身去恢復處理。