編輯:關於Android編程
為何產生
同時適配手機和平板、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是標簽的父標簽對應對象,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
繼承Fragment,重寫onCreateView決定Fragment的布局
在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)
getFragmentManager() // Fragment若使用的是support.v4包中的,那就使用getSupportFragmentManager代替
主要的操作都是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
上一篇文章中我們講解了android產品研發過程中的代碼Review。通過代碼Review能夠提高產品質量,增強團隊成員之間的溝通,提高開發效率,所以良好的產品開發迭代過
一、Android活動活動是 Android 應用框架中的一個核心組件,它在一個窗口(Window)對象中繪制用戶接口並響應用戶的交互。Android四大核心組件分別為A
在學習新內容之前,我們先來弄清楚兩個問題:1 . 什麼是ViewGroup?ViewGroup是一種容器。它包含零個或以上的View及子View。2 . ViewGrou
效果圖如下(笑話收縮效果):view的一個類(自定義布局類)public class MyImageView extends ImageView{ private s