Zunächst ein kleiner Hintergrund:
Ich habe ein Layout in einer Bildlaufansicht. Wenn der Benutzer auf dem Bildschirm einen Bildlauf durchführt, wird zunächst ein Bildlauf in der Bildlaufansicht durchgeführt. Nach einer gewissen Anzahl von Bildläufen sollte ich jedoch den Bildlauf in der Bildlaufansicht deaktivieren und den "Bildlauffokus" auf eine Webansicht innerhalb des untergeordneten Layouts verschieben. Auf diese Weise bleibt die Bildlaufansicht erhalten und alle Bildlaufereignisse gelangen in die darin enthaltene Webansicht.
Wenn eine Bildlaufschwelle erreicht ist, entferne ich für eine Lösung das untergeordnete Layout aus der Bildlaufansicht und füge es in das übergeordnete Element der Bildlaufansicht ein (und mache die Bildlaufansicht unsichtbar).
// 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);
Allgemeine Idee: (-> bedeutet enthält)
Vorher: Elternlayout -> Bildlaufansicht -> scrollChildLayout
Nachher: parentLayout -> scrollChildLayout
Der obige Code gibt mir diese Ausnahme:
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)
Weißt du was los ist? Ich rufe eindeutig removeView auf dem übergeordneten Element auf.
quelle
scrollView.removeView(scrollChildLayout)
versuchen, das Kind von scrollView zu entfernen, nicht das scrollView selbst von seiner übergeordneten ViewGroup zu entfernenif (mAdView.getParent()!=null) ((ViewGroup) mAdView.getParent()).removeView(mAdView);
Versuchen Sie zuerst, scrollChildLayout aus der übergeordneten Ansicht zu entfernen.
Oder entfernen Sie das gesamte untergeordnete Element aus der übergeordneten Ansicht und fügen Sie es erneut hinzu.
quelle
In onCreate mit Aktivität oder in onCreateView mit Fragment.
quelle
Ok, nenn mich paranoid, aber ich schlage vor:
Casting ohne
instanceof
scheint einfach falsch. Und (danke IntelliJ IDEA, dass Sie es mir gesagt haben)removeView
ist Teil derViewManager
Benutzeroberfläche. Und man sollte nicht in eine konkrete Klasse werfen, wenn eine perfekt geeignete Schnittstelle verfügbar ist.quelle
Alles, was Sie tun müssen, ist post () ein Runnable, das addView () ausführt.
quelle
Ich habe parentView.removeView (childView) aufgerufen und childView wurde immer noch angezeigt. Schließlich stellte ich fest, dass eine Methode zweimal ausgelöst wurde, und fügte die childView zweimal der parentView hinzu.
Verwenden Sie also parentView.getChildCount (), um zu bestimmen, wie viele untergeordnete Elemente das übergeordnete Element hat, bevor Sie eine Ansicht hinzufügen und danach. Wenn das untergeordnete Element zu oft hinzugefügt wird, wird das oberste untergeordnete Element entfernt und die Kopie childView bleibt erhalten. Dies sieht so aus, als würde removeView auch dann funktionieren, wenn dies der Fall ist.
Außerdem sollten Sie View.GONE nicht verwenden, um eine Ansicht zu entfernen. Wenn es wirklich entfernt wurde, müssen Sie es nicht verstecken, sonst ist es immer noch da und Sie verstecken es nur vor sich selbst :(
quelle
In meinem Fall habe ich BaseFragment und alle anderen Fragmente erben davon.
Also war meine Lösung, diese Zeilen in der
OnDestroyView()
Methode hinzuzufügenquelle
Kotlin-Lösung
Kotlin vereinfacht das übergeordnete Casting mit
as?
und gibt null zurück, wenn die linke Seite null ist oder das Casting fehlschlägt.Kotlin-Erweiterungslösung
Wenn Sie dies noch weiter vereinfachen möchten, können Sie diese Erweiterung hinzufügen.
Es wird sicher nichts tun, wenn diese Ansicht null ist, die übergeordnete Ansicht null ist oder die übergeordnete Ansicht keine ViewGroup ist
quelle
Sie können dies auch tun, indem Sie überprüfen, ob die indexOfView-Methode von View verwendet wird, wenn die indexOfView-Methode -1 zurückgibt.
DetectViewFromParent (v) von ViewGroup; gefolgt von removeDetachedView von ViewGroup (v, true / false);
quelle
Was ich falsch gemacht habe, also habe ich diesen Fehler bekommen, ist, dass ich kein dynamisches Layout instanziiert und Kinder hinzugefügt habe, also habe ich diesen Fehler bekommen
quelle
Hier ist meine Lösung.
Nehmen wir an, Sie haben zwei
TextViews
und setzen sie auf einenLinearLayout
(benanntenll
). Du wirst dasLinerLayout
auf einen anderen setzenLinerLayout
.Wenn Sie diese Struktur erstellen möchten, müssen Sie übergeordnetes Element als Vererbung angeben.
Wenn Sie es in einer
onCreate
Methode verwenden möchten,this
reicht dies aus.Ansonsten ist hier Solition:
quelle