嵌套Fragment的使用及遇到The specified child already has...

嵌套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();              }          } 

相關文章
相關標籤/搜索