Llame a removeView () en el padre del niño primero

Primero un poco de historia:

Tengo un diseño dentro de una vista de desplazamiento. Al principio, cuando el usuario se desplaza por la pantalla, la vista de desplazamiento se desplaza. Sin embargo, después de una cierta cantidad de desplazamiento, debía deshabilitar el desplazamiento en la vista de desplazamiento, mover el “enfoque de desplazamiento” a una vista web dentro del diseño secundario. De esta manera, las barras de desplazamiento y todos los eventos de desplazamiento van a la vista web dentro de ella.

Entonces, para una solución, cuando se alcanza el umbral de desplazamiento, elimino el diseño secundario de la vista de desplazamiento y lo coloco en el elemento primario de scrollview (y hago que la vista de desplazamiento sea invisible).

// 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); 

Idea general: (-> medio contiene)

Antes: parentlayout -> scrollview -> scrollChildLayout

Después: parentLayout -> scrollChildLayout

El código anterior me está dando esta excepción:

 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) 

¿Sabes lo que está pasando? Claramente llamo removeView al padre.

Solución:

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

Use el elemento hijo para obtener una referencia al padre. Transmita el elemento primario a un grupo de visualización para que tenga acceso al método removeView y lo use.

Gracias a @Dongshengcn por la solución

Intenta eliminar scrollChildLayout de su vista principal primero?

 scrollview.removeView(scrollChildLayout) 

O elimine todo el elemento secundario de la vista principal y agréguelos de nuevo.

 scrollview.removeAllViews() 

En onCreate con actividad o en onCreateView con fragmento.

  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) { } 

Ok, llámame paranoico pero sugiero:

  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 

lanzar sin instanceof solo parece estar mal. Y (gracias a IntelliJ IDEA por decirme) removeView es parte de la interfaz de ViewManager . Y uno no debería lanzar a una clase concreta cuando una interfaz perfectamente adecuada está disponible.

Todo lo que tienes que hacer es publicar () un Runnable que haga el addView ().

Estaba llamando a parentView.removeView (childView) y todavía se estaba mostrando childView. Finalmente me di cuenta de que un método se estaba desencadenando de alguna manera dos veces y agregué el childView a parentView dos veces.

Por lo tanto, use parentView.getChildCount () para determinar cuántos hijos tiene el padre antes de agregar una vista y luego. Si el elemento secundario se agrega demasiadas veces, se eliminará la parte superior del elemento secundario y se conservará la copia childView, que parece que removeView funciona incluso cuando lo está.

Además, no debe usar View.GONE para eliminar una vista. Si se elimina realmente, no será necesario que lo ocultes; de lo contrario, seguirá allí y solo lo ocultas 🙁

En mi caso, tengo BaseFragment y todos los otros fragmentos heredan de esto.

Así que mi solución fue agregar estas líneas en el método OnDestroyView()

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

También puede hacerlo comprobando si el método indexOfView de View si el método indexOfView devuelve -1, entonces podemos usarlo.

ViewGroup’s detachViewFromParent (v); seguido por removeDetachedView de ViewGroup (v, verdadero / falso);

Lo que estaba haciendo mal, así que obtuve este error es que no estaba creando una instancia de diseño dynamic y agregando elementos secundarios, así que obtuve este error

Aquí está mi solución.

Digamos que tienes dos TextViews y los TextViews en LinearLayout (llamado ll ). LinerLayout este LinerLayout en otro LinerLayout .

 < lm Linear Layout> < ll Linear Layout>       

Cuando desee crear esta estructura, debe otorgarle herencia a los padres.

Si desea usarlo en un método onCreate , this será suficiente.

De lo contrario, aquí está la solución:

 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());