Appelez removeView () sur le parent de l’enfant en premier

Tout d’abord un petit arrière-plan:

J’ai une mise en page dans une vue de défilement. Au début, lorsque l’utilisateur fait défiler l’écran, le défilement défile. Cependant, après une certaine quantité de défilement, je devais désactiver le défilement de la vue de défilement pour déplacer le “focus de défilement” sur une vue Web dans la mise en page enfant. De cette façon, la vue de défilement se colle et tous les événements de défilement vont dans la vue Web à l’intérieur.

Donc, pour une solution, lorsque le seuil de défilement est atteint, je supprime la mise en page enfant de la vue de défilement et la place dans le parent de scrollview (et rend la vue de défilement 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); 

Idée générale: (-> signifie contient)

Avant: parentlayout -> scrollview -> scrollChildLayout

Après: parentLayout -> scrollChildLayout

Le code ci-dessus me donne cette exception:

 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) 

Savez-vous ce qui se passe? J’appelle clairement removeView sur le parent.

Solution:

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

Utilisez l’élément enfant pour obtenir une référence au parent. Transmettez le parent à un ViewGroup pour avoir access à la méthode removeView et l’utiliser.

Merci à @Dongshengcn pour la solution

Essayez d’abord de supprimer scrollChildLayout de sa vue parent?

 scrollview.removeView(scrollChildLayout) 

Ou supprimez tous les enfants de la vue parent et ajoutez-les à nouveau.

 scrollview.removeAllViews() 

Dans onCreate with activity ou dans onCreateView avec fragment.

  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, appelez-moi paranoïaque mais je suggère:

  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 

le casting sans instanceof semble juste faux. Et (merci à IntelliJ IDEA de m’avoir dit) removeView fait partie de l’interface de ViewManager . Et il ne faut pas lancer une classe concrète lorsqu’une interface parfaitement adaptée est disponible.

Tout ce que vous avez à faire est de poster () un Runnable qui fait l’addView ().

J’appelais parentView.removeView (childView) et childView était toujours affiché. J’ai finalement réalisé qu’une méthode était en quelque sorte déclenchée deux fois et ajoutait childView au parent View deux fois.

Par conséquent, utilisez parentView.getChildCount () pour déterminer le nombre d’enfants que le parent possède avant d’append une vue et par la suite. Si l’enfant est ajouté trop de fois, le plus petit des enfants est supprimé et la copie que garde childView – qui ressemble à removeView fonctionne même quand c’est le cas.

En outre, vous ne devez pas utiliser View.GONE pour supprimer une vue. Si elle est vraiment supprimée, vous n’avez pas besoin de la cacher, sinon elle est toujours là et vous la cachez simplement 🙁

Dans mon cas, j’ai BaseFragment et tous les autres fragments en héritent.

Donc, ma solytion a été ajouté cette ligne dans la méthode 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(); } 

Vous pouvez également le faire en vérifiant si la méthode indexOfView de View si la méthode indexOfView retourne -1 alors nous pouvons utiliser.

DetachViewFromParent (v) de ViewGroup; suivi de removeDetachedView de ViewGroup (v, true / false);

Ce que je faisais mal alors j’ai eu cette erreur est que je n’étais pas instanciant la disposition dynamic et en ajoutant des enfants à elle a obtenu cette erreur

Voici ma solution

Disons que vous avez deux TextViews et les mettez sur un LinearLayout (nommé ll ). Vous allez mettre ce LinerLayout sur un autre LinerLayout .

 < lm Linear Layout> < ll Linear Layout>       

Lorsque vous souhaitez créer cette structure, vous devez donner le parent en inheritance.

Si vous voulez l’utiliser dans une méthode onCreate , this suffit.

Sinon, voici la solition:

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