2011-06-29 55 views
128

第一個小背景:先調用小孩父母的removeView()第一個

我有一個滾動視圖內的佈局。首先,當用戶在屏幕上滾動時,滾動視圖會滾動。但是,在一定數量的滾動後,我將禁用滾動視圖上的滾動,將「滾動焦點」移動到子佈局內的web視圖上。這樣,滾動視圖就會粘住,所有滾動事件都會轉到其中的webview。因此,對於解決方案,當達到滾動閾值時,我從滾動視圖中移除子佈局,並將其放置在滾動視圖的父級(並使滾動視圖不可見)。

// Remove the child view from the scroll view 
scrollView.removeView(scrollChildLayout); 

// Get scroll view out of the way 
scrollView.setVisibility(View.GONE); 

// Put the child view into scrollview's parent view 
parentLayout.addView(scrollChildLayout); 

總體思路:( - >手段包含)

之前:parentlayout - >滾動視圖 - > scrollChildLayout

後:parentLayout - > scrollChildLayout

上面的代碼是給我這個例外:

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. 
      at android.view.ViewGroup.addViewInner(ViewGroup.java:1976) 
      at android.view.ViewGroup.addView(ViewGroup.java:1871) 
      at android.view.ViewGroup.addView(ViewGroup.java:1828) 
      at android.view.ViewGroup.addView(ViewGroup.java:1808) 

你知道發生了什麼事嗎?我清楚地調用父級的removeView。

回答

269

解決方案:

((ViewGroup)scrollChildLayout.getParent()).removeView(scrollChildLayout); 
//scrollView.removeView(scrollChildLayout); 

使用子元素才能到父級的引用。將父項轉換爲ViewGroup,以便可以訪問removeView方法並使用它。

感謝@Dongshengcn爲解決

+14

+1 getParent()是這裏的寶石。 –

+1

解決方案是正確的,但爲什麼「scollView.removeView(scrollChildLayout)」不起作用?兩條線不應該是一樣的嗎? –

+0

@ andrea.spot,看起來像'scrollView.removeView(scrollChildLayout)'試圖刪除scrollView的孩子,而不是從其父ViewGroup –

22

嘗試先從其父視圖中移除scrollChildLayout?

scrollview.removeView(scrollChildLayout) 

或者從父視圖中刪除所有子項,然後再次添加它們。

scrollview.removeAllViews() 
+0

我已經在我的問題調用removeView在上面的代碼。 removeAllViews()也不起作用。 – kasgoku

+0

您確定它是您要調用的父級removeView()/ removeAllViews()?我做了非常類似的事情,它一直在爲我工作。 – dongshengcn

+4

您可以通過查看其父項:view.getParent()http://developer.android.com/reference/android/view/View.html#getParent() – dongshengcn

2

所有你需要做的就是post()一個可以執行addView()的Runnable。

+0

沒有工作。這是我試過的: scrollView.removeView(scrollChildLayout); scrollView.setVisibility(View.GONE); parentLayout.post(新的Runnable(){ @Override 公共無效的run(){ parentLayout.addView(scrollChildLayout); } }); – kasgoku

0

您也可以通過檢查視圖的indexOfView方法 如果indexOfView方法返回-1,那麼我們就可以用做。

ViewGroup的detachViewFromParent(v); 後面跟着 ViewGroup的removeDetachedView(v,true/false);

15

好了,叫我偏執,但我建議:

final android.view.ViewParent parent = view.getParent(); 

    if (parent instanceof android.view.ViewManager) 
    { 
    final android.view.ViewManager viewManager = (android.view.ViewManager) parent; 

    viewManager.removeView (view); 
    } // if 

鑄造沒有instanceof似乎只是錯誤的。並且(感謝IntelliJ IDEA告訴我)removeViewViewManager界面的一部分。當一個完美合適的界面可用時,你不應該投入具體的課程。

1

我正在調用parentView.removeView(childView)和childView仍然顯示。我最終意識到,某種方法被觸發了兩次,並將childView添加到父視圖兩次。

因此,使用parentView.getChildCount()來確定在添加視圖之前以及隨後的父視圖中有多少個子項。如果孩子被添加太多次,那麼最上面的孩子將被刪除,並且複製childView仍然存在 - 這看起來像removeView正在工作,即使它是。

此外,您不應該使用View.GONE刪除視圖。如果它的真正刪除,那麼你將不再需要隱藏它,否則它仍然存在,你就剛剛從自己與活動或onCreateView與片段隱藏它:(

18

在的onCreate。

if (view != null) { 
    ViewGroup parent = (ViewGroup) view.getParent(); 
    if (parent != null) { 
     parent.removeView(view); 
    } 
} 
try { 
    view = inflater.inflate(R.layout.fragment_main, container, false); 
} catch (InflateException e) { 

} 
0

我在做什麼錯了,所以我得到這個錯誤是我沒有實例化動態佈局,增加孩子的它,因此得到這個錯誤

1

在我的情況,我有BaseFragment和所有其他片段從這個繼承。

所以我的解決方法是在添加這行方法

@Override 
public final View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{ 
    if (mRootView == null) 
    { 
     mRootView = (inflater == null ? getActivity().getLayoutInflater() : inflater).inflate(mContentViewResourceId, container, false); 
    } 
....//// 
} 

@Override 
public void onDestroyView() 
{ 
    if (mRootView != null) 
    { 
     ViewGroup parentViewGroup = (ViewGroup) mRootView.getParent(); 

     if (parentViewGroup != null) 
     { 
      parentViewGroup.removeAllViews(); 
     } 
    } 

    super.onDestroyView(); 
} 
0

這是我的解決方案。

假設您有兩個TextViews並將它們放在LinearLayout(名爲ll)。你會把這個LinerLayout放在另一個LinerLayout

< lm Linear Layout> 
     < ll Linear Layout> 
      <name Text view> 
      </name Text view> 
      <surname Text view> 
      </surname Text view> 
     </ll Linear Layout> 
</lm Linear Layout> 

當你想要創建這個結構時,你需要給父類作爲繼承。

如果你想用它在onCreate方法this就夠了。

否則這裏是孤子:

LinerLayout lm = new LinearLayout(this); // You can use getApplicationContext() also 
LinerLayout ll = new LinearLayout(lm.getContext()); 
TextView name = new TextView(ll.getContext()); 
TextView surname = new TextView(ll.getContext()); 
相關問題