嵌套Tab在Android應用中用途普遍,以前作過的一些東西都是運用了TabActivity。可是因爲在Android Developers中說到了「TabActivity was deprecated in API level 13." ,而且建議你們使用Fragment。因此學習了嵌套Fragment的使用,參考了這個博客中的相關思路和代碼。 java
在Android Developers中對於Fragment(中文版看這裏)的描述:A Fragment represents a behaviors or a portion of user interface in an Activity. You can combine multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple activities. You can think of a fragment as a modular section of an activity, which has its own lifecycle, receives its own input events, and which you can add or remove while the activity is running.
簡單來講,Fragment就是被嵌入在Activity中用來表現UI的一個可模塊化和可重用的組件。Fragment在大屏幕設備中應用能夠很是普遍,開發者能夠經過本身巧妙的設計讓UI更加靈活和美觀。 android
建立Fragment
建立Fragment,必須建立一個Fragment的子類。
建立一個本身的Fragment,須要建立一個Fragment的子類。Fragment的生命週期和Activity的生命週期相似,它包含了不少與Activity相似的回調函數。 模塊化
[java]
public void onCreate (Bundle savedInstanceState) 函數
public void onCreate (Bundle savedInstanceState)建立fragment的時候調用onCreate()方法
[java]
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 佈局
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)在第一次繪製UI的時候系統調用該方法,爲了繪製UI,返回一個fragment佈局的根View。 學習
將Fragment添加到Activity的方法
1.在layout文件中聲明fragment ui
[plain]
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1.0"
android:background="#fffab3" >
</FrameLayout> spa
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1.0"
android:background="#fffab3" >
</FrameLayout> 設計
2.將一個fragment添加到viewgroup中,使用FragmentTransaction添加、替換或者刪除fragment。 調試
[java]
private void addFragmentToStack(Fragment fragment) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, fragment);
ft.commit();
}
private void addFragmentToStack(Fragment fragment) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, fragment);
ft.commit();
}Fragment生命週期
異常分析
關於解決 java.lang.IllegalStateException The specified child already has a parent. You must call removeView()的方法
在運行調試的時候會發現,在第二次點擊一個相同的tab的時候,會出現上述異常。
這個異常說的是,這個特定的child view已經存在一個parent view了,必須讓parent view調用removeView()方法。
通過對fragment的生命週期的分析
運行順序:點擊tab1,點擊tab2,再點擊tab1.
能夠發現,出問題的是viewpager中的view。當切換不一樣的viewpager(即fragment,每一個fragment中裝載了一個viewpager)時,調用了startActivity()方法的時候,傳入了相同的id,會返回相同的對象。而當咱們在第二次調用的時候,傳入了相同的id是複用了原來的view,這就致使了view被指定多個parent view。
因此解決辦法就是,在使用這個view以前首先判斷其是否存在parent view,這調用getParent()方法能夠實現。若是存在parent view,那麼就調用removeAllViewsInLayout()方法。代碼以下:
[java] for (View view : viewList) { ViewGroup p = (ViewGroup) view.getParent(); if (p != null) { p.removeAllViewsInLayout(); } }