Fragment之個人解決方案:Fragmentation

Fragment系列文章:
一、Fragment全解析系列(一):那些年踩過的坑
二、Fragment全解析系列(二):正確的使用姿式
三、Fragment之個人解決方案:Fragmentationjava

若是你通讀了本系列的前兩篇,我相信你能夠寫出大部分場景都能正常運行的Fragment了。若是你想了解更多,那麼你能夠看看我封裝的這個庫:Fragmentation。
本篇主要介紹這個庫,解決了一些BUG,使用簡單,提供實時查看棧視圖等實用功能。git


源碼地址:Github,歡迎Fork,提Issues 。github

Demo網盤下載
Demo演示:單Activity+多Fragment架構


demo.gif

Fragmentation

爲"單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

API

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){ // 在此能夠接收到數據 }

關於Fragmentation幫你恢復Fragment,你須要知道的

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嵌套,那麼無論是「同級」式仍是「流程」式,你都須要本身去恢復處理。



文/YoKeyword(簡書做者) 原文連接:http://www.jianshu.com/p/38f7994faa6b 著做權歸做者全部,轉載請聯繫做者得到受權,並標註「簡書做者」。
相關文章
相關標籤/搜索