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

來源:互聯網
上載者:User

預備知識

 

嵌套Tab在Android應用中用途廣泛,之前做過的一些東西都是運用了TabActivity。但是由於在Android Developers中說到了“TabActivity was deprecated in API level 13." ,並且建議大家使用Fragment。所以學習了嵌套Fragment的使用,參考了這個部落格中的相關思路和代碼。

 


在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更加靈活和美觀。

 

建立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


[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> 

  <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.

具體fragment的生命週期是:

 

 


對進行分析,可以發現,出問題的是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(); 
            } 
        } 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.