Android-Layout ersetzt eine Ansicht zur Laufzeit durch eine andere Ansicht


175

Ich habe eine xml-layout-Datei main mit zwei Textansichten A / B und einer Ansicht C. Ich habe zwei andere xml-layout-Dateien option1und option2. Ist es möglich, entweder option1oder option2zur Laufzeit über Java in C zu laden ? Wenn ja, welche Funktion muss ich verwenden?

Antworten:


372

Sie können jede Ansicht jederzeit ersetzen.

int optionId = someExpression ? R.layout.option1 : R.layout.option2;

View C = findViewById(R.id.C);
ViewGroup parent = (ViewGroup) C.getParent();
int index = parent.indexOfChild(C);
parent.removeView(C);
C = getLayoutInflater().inflate(optionId, parent, false);
parent.addView(C, index);

Wenn Sie die bereits vorhandene Ansicht nicht ersetzen möchten , sondern bei der Initialisierung zwischen Option1 / Option2 wählen möchten, können Sie dies einfacher tun: Legen Sie das android:idübergeordnete Layout fest und dann:

ViewGroup parent = (ViewGroup) findViewById(R.id.parent);
View C = getLayoutInflater().inflate(optionId, parent, false);
parent.addView(C, index);

Sie müssen "index" abhängig von der Ansichtsstruktur auf den richtigen Wert setzen. Sie können auch einen ViewStub verwenden : Fügen Sie Ihre C-Ansicht als ViewStub hinzu und dann:

ViewStub C = (ViewStub) findViewById(R.id.C);
C.setLayoutResource(optionId);
C.inflate();

Auf diese Weise müssen Sie sich keine Gedanken über den "Index" -Wert machen, wenn Sie Ihr XML-Layout neu strukturieren möchten.


Muss ich das Fragment entfernen oder wird das Fragment auch entfernt?
K - Die Toxizität in SO nimmt zu.

3
@KarlMorrison Diese Frage ist fast 4 Jahre alt und hat nichts mit Fragmenten zu tun. Ich schlage vor, eine neue Frage zu stellen und / oder einen Blick darauf zu werfen android.app.FragmentTransactionund die replace()Methode.
Lupz

Es ist schade, dass Ihre Antwort zu komplex ist - in den Kommentaren - für unerfahrene Android-Programmierer :-(
Antonio Sesto

2
@AntonioSesto was ist zu komplex? Wo hast du dich verwirrt?
AdamMc331

@broot Ich möchte Bilder täglich zu meinem linearen Layout hinzufügen, das ich erstellt habe. später entferne ich einige Bilder aus dem Layout. dann möchte ich es an seiner eigenen Position wiederherstellen, von der ich es entfernt habe. bedeutet, dass ich Bilder hinzufügen möchte, ohne die Eltern des Kindes zu entfernen. Können Sie mir bitte helfen?
PriyankaChauhan

43

Und wenn Sie dies sehr oft tun, können Sie einen ViewSwitcher oder einen ViewFlipper verwenden , um das Ersetzen der Ansicht zu vereinfachen.


Ja, wenn es um alternative Ansichten geht, ist es besser, die Ansicht Flipper / Switcher zu verwenden
Zoombie

2
@Shail Adi, haben Sie versucht, einen ViewSwitcher-Tutorial-Code zu erstellen?
Snicolas

Ich weiß, dass dies alt ist - aber die Einschränkung ist, dass ein ViewSwitcher beide Ansichten initialisiert und in sich behält (ein FrameLayout).
Vikram Bodicherla

Dies sollte die empfohlene Antwort sein. Warum nicht einfach eine fertige, gut getestete Lösung verwenden?

3
private void replaceView(View oldV,View newV){
        ViewGroup par = (ViewGroup)oldV.getParent();
        if(par == null){return;}
        int i1 = par.indexOfChild(oldV);
        par.removeViewAt(i1);
        par.addView(newV,i1);
    }

6
Während dieser Code die Frage beantworten kann, würde die Bereitstellung eines zusätzlichen Kontexts darüber, wie und / oder warum das Problem gelöst wird, den langfristigen Wert der Antwort verbessern
frobinsonj

0

es funktioniert in meinem Fall, oldSensor und newSnsor - oldView und newView:

private void replaceSensors(View oldSensor, View newSensor) {
            ViewGroup parent = (ViewGroup) oldSensor.getParent();

            if (parent == null) {
                return;
            }

            int indexOldSensor = parent.indexOfChild(oldSensor);
            int indexNewSensor = parent.indexOfChild(newSensor);
            parent.removeView(oldSensor);
            parent.addView(oldSensor, indexNewSensor);
            parent.removeView(newSensor);
            parent.addView(newSensor, indexOldSensor);
        }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.