2013-09-05 64 views
11

其實,我一直重用我在我的片段,如以下幾種觀點:片段 - 我應該在onCreateView中重用視圖,我應該怎麼做?

private View mView = null; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{ 
    if (mView == null) 
     mView = inflater.inflate(R.layout.view); 
    return mView; 
} 

這工作,與viewpager等。現在,我開始使用我的簡單的活動片段,以及如果,且僅當,我的片段添加到堆棧中,這將失敗,因爲java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

所以我的問題是:

  • 它是確定,如果我檢查父視圖,將其刪除並將其添加到新的父級?
  • 或者我應該總是重新創建視圖並且永不重複使用它?如果是,爲什麼?
  • 有沒有其他的觀點,重用視圖會失敗?

回答

11

也許這可以幫助理解行爲。如果檢查出FragmentManagerImpl.java你會發現以下內容:

首先,我們通過調用onCreateView()線845),然後我們總結創建的視圖與另一種觀點認爲,這成爲我們的觀點的父(線848創建一個視圖-849)。這意味着我們的觀點不會成爲真正的容器的孩子,但它現在是一個包裝視圖的孩子。當視圖從容器中移除時(行998),重新使用問題就會發生。 FragmentManager從容器中移除包裝器視圖,但我們的真實視圖保持添加到父包裝器視圖。這是導致您遇到問題的原因。

因此,如果您從其父項中刪除視圖,它可以工作。即使知道這一點,我也不建議在片段中重複使用視圖,因爲視圖的存活時間可能比片段長一些,因爲即使片段被銷燬後,它們也可以用於「消失」的動畫中。如果您嘗試在當時從其父級移除此類視圖,那麼動畫可能會被破壞。

另一個不緩存視圖的理由是,Android不支持按設計分段瀏覽視圖。記得ListAdapter允許重複使用視圖嗎? Android負責緩存並正確重用這些視圖。儘管這不是碎片的情況。

+0

感謝您的解釋,這使我更清楚 – prom85

6

我目前重用的是這樣的觀點:

if(view == null){ 
    view = (ViewGroup) inflater.inflate(R.layout.news_list, container, false); 
} else { 
    ((ViewGroup) view.getParent()).removeView(view); 
} 
return view; 

我不知道這種方式是正確的,但它似乎爲我工作..

注:我使用這個aproach,因爲我有一個片段的列表視圖,當用戶點擊一個項目時,它會加載一個新的片段(片段管理器使用替換當前列表片段)。然後,當用戶點擊後退按鈕時,由於我重複使用了片段的相同舊視圖(用FM刪除時未破壞),用戶繼續在打開詳細片段視圖之前的位置查看列表。

+0

嗨@edrain您的解決方案工作正常,但它不是從容器中刪除視圖,即使我已經彈出我的片段。 –