Mise en page Android remplaçant une vue par une autre au moment de l'exécution


175

J'ai un xmlfichier -layout principal avec deux textviews A / B et une vue C. J'ai deux autres xmlfichiers -layout option1et option2. Est-il possible de charger soit option1ou option2à l'exécution via Java dans C? Si oui, quelle fonction dois-je utiliser?

Réponses:


372

Vous pouvez remplacer n'importe quelle vue à tout moment.

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

Si vous ne souhaitez pas remplacer déjà existant Voir , mais choisir entre option1 / option2 au moment de l' initialisation, vous pouvez le faire plus facilement: ensemble android:idpour la mise en page de parent puis:

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

Vous devrez définir "index" à la valeur appropriée en fonction de la structure des vues. Vous pouvez également utiliser un ViewStub : ajoutez votre vue C en tant que ViewStub puis:

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

De cette façon, vous n'aurez pas à vous soucier de la valeur "index" ci-dessus si vous souhaitez restructurer votre mise en page XML.


Dois-je supprimer le fragment ou le fragment sera-t-il également supprimé?
K - La toxicité du SO augmente.

3
@KarlMorrison Cette question a presque 4 ans et n'a rien à voir avec des fragments. Je suggère de déposer une nouvelle question et / ou de jeter un œil à android.app.FragmentTransactionsa replace()méthode.
lupz du

Il est dommage que votre réponse soit trop complexe - dans les commentaires - pour les programmeurs Android novices :-(
Antonio Sesto

2
@AntonioSesto ce qui est trop complexe? Où avez-vous été confus?
AdamMc331 du

@broot Je veux ajouter des images daynamiquement à ma disposition linéaire que j'ai faite. plus tard, je supprime certaines images de la mise en page. alors je veux le restaurer à sa propre position d'où j'ai supprimé. signifie que je veux ajouter des images sans supprimer le parent de l'enfant, pouvez-vous s'il vous plaît m'aider?
PriyankaChauhan

43

Et si vous faites cela très souvent, vous pouvez utiliser un ViewSwitcher ou un ViewFlipper pour faciliter la substitution de vue.


Oui, s'il est question de vues alternatives, il est préférable d'utiliser le flipper / switcher de vue
Zoombie

2
@Shail Adi, avez-vous essayé de goole un code de tutoriel ViewSwitcher?
Snicolas

Je sais que c'est vieux - mais la mise en garde est qu'un ViewSwitcher initialise et contient les deux vues en soi (un FrameLayout).
Vikram Bodicherla

Cela devrait être la réponse recommandée. Pourquoi ne pas simplement utiliser une solution prête à l'emploi et bien testée.

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
Bien que ce code puisse répondre à la question, fournir un contexte supplémentaire sur la manière et / ou pourquoi il résout le problème améliorerait la valeur à long terme de la réponse
frobinsonj

0

cela fonctionne dans mon cas, oldSensor et newSnsor - oldView et 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);
        }
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.