#Fragment
##為何產生
* 同時適配手機和平板、UI和邏輯的共享。
##介紹
* Fragment也會被加入回退棧中。
* Fragment擁有自己的生命周期和接受、處理用戶的事件
* 可以動態的添加、替換和移除某個Fragment
##生命周期
* 必須依存于Activity

* Fragment依附于Activity的生命狀態
* 
生命周期中那么多方法,懵逼了的話我們就一起來看一下每一個生命周期方法的含義吧。
##Fragment生命周期方法含義:
* `public void onAttach(Context context)`
* onAttach方法會在Fragment于窗口關聯后立刻調用。從該方法開始,就可以通過Fragment.getActivity方法獲取與Fragment關聯的窗口對象,但因為Fragment的控件未初始化,所以不能夠操作控件。
* `public void onCreate(Bundle savedInstanceState)`
* 在調用完onAttach執行完之后立刻調用onCreate方法,可以在Bundle對象中獲取一些在Activity中傳過來的數據。通常會在該方法中讀取保存的狀態,獲取或初始化一些數據。在該方法中不要進行耗時操作,不然窗口不會顯示。
* `public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)`
* 該方法是Fragment很重要的一個生命周期方法,因為會在該方法中創建在Fragment顯示的View,其中inflater是用來裝載布局文件的,container是`<fragment>`標簽的父標簽對應對象,savedInstanceState參數可以獲取Fragment保存的狀態,如果未保存那么就為null。
* `public void onViewCreated(View view,Bundle savedInstanceState)`
* Android在創建完Fragment中的View對象之后,會立刻回調該方法。其種view參數就是onCreateView中返回的view,而bundle對象用于一般用途。
* `public void onActivityCreated(Bundle savedInstanceState)`
* 在Activity的onCreate方法執行完之后,Android系統會立刻調用該方法,表示窗口已經初始化完成,從這一個時候開始,就可以在Fragment中使用getActivity().findViewById(Id);來操控Activity中的view了。
* `public void onStart()`
* 這個沒啥可講的,但有一個細節需要知道,當系統調用該方法的時候,fragment已經顯示在ui上,但還不能進行互動,因為onResume方法還沒執行完。
* `public void onResume()`
* 該方法為fragment從創建到顯示Android系統調用的最后一個生命周期方法,調用完該方法時候,fragment就可以與用戶互動了。
* `public void onPause()`
* fragment由活躍狀態變成非活躍狀態執行的第一個回調方法,通常可以在這個方法中保存一些需要臨時暫停的工作。如保存音樂播放進度,然后在onResume中恢復音樂播放進度。
* `public void onStop()`
* 當onStop返回的時候,fragment將從屏幕上消失。
* `public void onDestoryView()`
* 該方法的調用意味著在 `onCreateView` 中創建的視圖都將被移除。
* `public void onDestroy()`
* Android在Fragment不再使用時會調用該方法,要注意的是~這時Fragment還和Activity藕斷絲連!并且可以獲得Fragment對象,但無法對獲得的Fragment進行任何操作(呵~呵呵~我已經不聽你的了)。
* `public void onDetach()`
* 為Fragment生命周期中的最后一個方法,當該方法執行完后,Fragment與Activity不再有關聯(分手!我們分手!!(╯‵□′)╯︵┻━┻)。
##Fragment比Activity多了幾個額外的生命周期回調方法:
* onAttach(Activity):當Fragment和Activity發生關聯時使用
* onCreateView(LayoutInflater, ViewGroup, Bundle):創建該Fragment的視圖
* onActivityCreate(Bundle):當Activity的onCreate方法返回時調用
* onDestoryView():與onCreateView相對應,當該Fragment的視圖被移除時調用
* onDetach():與onAttach相對應,當Fragment與Activity關聯被取消時調用
###注意:除了onCreateView,其他的所有方法如果你重寫了,必須調用父類對于該方法的實現
##Fragment與Activity之間的交互
* Fragment與Activity之間的交互可以通過`Fragment.setArguments(Bundle args)`以及`Fragment.getArguments()`來實現。
##Fragment狀態的持久化。
由于Activity會經常性的發生配置變化,所以依附它的Fragment就有需要將其狀態保存起來問題。下面有兩個常用的方法去將Fragment的狀態持久化。
* 方法一:
* 可以通過`protected void onSaveInstanceState(Bundle outState)`,`protected void onRestoreInstanceState(Bundle savedInstanceState)` 狀態保存和恢復的方法將狀態持久化。
* 方法二(更方便,讓Android自動幫我們保存Fragment狀態):
* 我們只需要將Fragment在Activity中作為一個變量整個保存,只要保存了Fragment,那么Fragment的狀態就得到保存了,所以呢.....
* `FragmentManager.putFragment(Bundle bundle, String key, Fragment fragment)` 是在Activity中保存Fragment的方法。
* `FragmentManager.getFragment(Bundle bundle, String key)` 是在Activity中獲取所保存的Frament的方法。
* 很顯然,key就傳入Fragment的id,fragment就是你要保存狀態的fragment,但,我們注意到上面的兩個方法,第一個參數都是Bundle,這就意味著*FragmentManager*是通過Bundle去保存Fragment的。但是,這個方法僅僅能夠保存Fragment中的控件狀態,比如說EditText中用戶已經輸入的文字(*注意!在這里,控件需要設置一個id,否則Android將不會為我們保存控件的狀態*),而Fragment中需要持久化的變量依然會丟失,但依然有解決辦法,就是利用方法一!
* 下面給出狀態持久化的事例代碼:
```
/** Activity中的代碼 **/
FragmentB fragmentB;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_activity);
if( savedInstanceState != null ){
fragmentB = (FragmentB) getSupportFragmentManager().getFragment(savedInstanceState,"fragmentB");
}
init();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
if( fragmentB != null ){
getSupportFragmentManager().putFragment(outState,"fragmentB",fragmentB);
}
super.onSaveInstanceState(outState);
}
/** Fragment中保存變量的代碼 **/
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
AppLog.e("onCreateView");
if ( null != savedInstanceState ){
String savedString = savedInstanceState.getString("string");
//得到保存下來的string
}
View root = inflater.inflate(R.layout.fragment_a,null);
return root;
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putString("string","anAngryAnt");
super.onSaveInstanceState(outState);
}
```
##靜態的使用Fragment
1. 繼承Fragment,重寫onCreateView決定Fragment的布局
2. 在Activity中聲明此Fragment,就和普通的View一樣
##Fragment常用的API
* android.support.v4.app.Fragment 主要用于定義Fragment
* android.support.v4.app.FragmentManager 主要用于在Activity中操作Fragment,可以使用FragmentManager.findFragmenById,FragmentManager.findFragmentByTag等方法去找到一個Fragment
* android.support.v4.app.FragmentTransaction 保證一些列Fragment操作的原子性,熟悉事務這個詞
* 主要的操作都是FragmentTransaction的方法
(一般我們為了向下兼容,都使用support.v4包里面的Fragment)
<code>
getFragmentManager() // Fragment若使用的是support.v4包中的,那就使用getSupportFragmentManager代替
</code>
* 主要的操作都是FragmentTransaction的方法
```
FragmentTransaction transaction = fm.benginTransatcion();//開啟一個事務
transaction.add()
//往Activity中添加一個Fragment
transaction.remove()
//從Activity中移除一個Fragment,如果被移除的Fragment沒有添加到回退棧(回退棧后面會詳細說),這個Fragment實例將會被銷毀。
transaction.replace()
//使用另一個Fragment替換當前的,實際上就是remove()然后add()的合體~
transaction.hide()
//隱藏當前的Fragment,僅僅是設為不可見,并不會銷毀
transaction.show()
//顯示之前隱藏的Fragment
detach()
//當fragment被加入到回退棧的時候,該方法與*remove()*的作用是相同的,
//反之,該方法只是將fragment從視圖中移除,
//之后仍然可以通過*attach()*方法重新使用fragment,
//而調用了*remove()*方法之后,
//不僅將Fragment從視圖中移除,fragment還將不再可用。
attach()
//重建view視圖,附加到UI上并顯示。
transatcion.commit()
//提交一個事務
```
##管理Fragment回退棧
* 跟蹤回退棧狀態
* 我們通過實現*``OnBackStackChangedListener``*接口來實現回退棧狀態跟蹤,具體如下
```
public class XXX implements FragmentManager.OnBackStackChangedListener
/** 實現接口所要實現的方法 **/
@Override
public void onBackStackChanged() {
//do whatevery you want
}
/** 設置回退棧監聽接口 **/
getSupportFragmentManager().addOnBackStackChangedListener(this);
```
* 管理回退棧
* ``FragmentTransaction.addToBackStack(String)`` *--將一個剛剛添加的Fragment加入到回退棧中*
* ``getSupportFragmentManager().getBackStackEntryCount()`` *-獲取回退棧中實體數量*
* ``getSupportFragmentManager().popBackStack(String name, int flags)`` *-根據name立刻彈出棧頂的fragment*
* ``getSupportFragmentManager().popBackStack(int id, int flags)`` *-根據id立刻彈出棧頂的fragment*
- JavaSE(Java基礎)
- Java基礎知識
- Java中的內存泄漏
- String源碼分析
- Java集合結構
- ArrayList源碼剖析
- HashMap源碼剖析
- Hashtable簡介
- Vector源碼剖析
- LinkedHashMap簡介
- LinkedList簡介
- JVM(Java虛擬機)
- JVM基礎知識
- JVM類加載機制
- Java內存區域與內存溢出
- 垃圾回收算法
- Java并發(JavaConcurrent)
- Java并發基礎知識
- 生產者和消費者問題
- Thread和Runnable實現多線程的區別
- 線程中斷
- 守護線程與阻塞線程的情況
- Synchronized
- 多線程環境中安全使用集合API
- 實現內存可見的兩種方法比較:加鎖和volatile變量
- 死鎖
- 可重入內置鎖
- 使用wait/notify/notifyAll實現線程間通信
- NIO
- 數據結構(DataStructure)
- 數組
- 棧和隊列
- Algorithm(算法)
- 排序
- 選擇排序
- 冒泡排序
- 快速排序
- 歸并排序
- 查找
- 順序查找
- 折半查找
- Network(網絡)
- TCP/UDP
- HTTP
- Socket
- OperatingSystem(操作系統)
- Linux系統的IPC
- android中常用設計模式
- 面向對象六大原則
- 單例模式
- Builder模式
- 原型模式
- 簡單工廠
- 策略模式
- 責任鏈模式
- 觀察者模式
- 代理模式
- 適配器模式
- 外觀模式
- Android(安卓面試點)
- Android基礎知識
- Android內存泄漏總結
- Handler內存泄漏分析及解決
- Android性能優化
- ListView詳解
- RecyclerView和ListView的異同
- AsyncTask源碼分析
- 插件化技術
- 自定義控件
- ANR問題
- Art和Dalvik的區別
- Android關于OOM的解決方案
- Fragment
- SurfaceView
- Android幾種進程
- APP啟動過程
- 圖片三級緩存
- Bitmap的分析與使用
- 熱修復的原理
- AIDL
- Binder機制
- Zygote和System進程的啟動過程
- Android中的MVC,MVP和MVVM
- MVP
- Android開機過程
- EventBus用法詳解
- 查漏補缺
- Git操作