Układ systemu Android zastępujący widok innym widokiem w czasie wykonywania

175

Mam xmlplik -layout main z dwoma widokami tekstowymi A / B i widokiem C. Mam dwa inne xmlpliki -layout option1i option2. Czy to możliwe, aby załadować albo option1czy option2w czasie wykonywania przez Java w C? Jeśli tak, jakiej funkcji mam użyć?

chrześcijanin
źródło

Odpowiedzi:

372

W każdej chwili możesz zamienić dowolny widok.

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

Jeśli nie chcesz zastępować już istniejącego widoku , ale wybierasz między opcją 1 / opcją 2 w czasie inicjalizacji, możesz to zrobić łatwiej: ustaw android:iddla układu nadrzędnego, a następnie:

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

Będziesz musiał ustawić "indeks" na odpowiednią wartość w zależności od struktury widoków. Możesz także użyć ViewStub : dodaj swój widok C jako ViewStub, a następnie:

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

W ten sposób nie będziesz musiał martwić się o wartość powyżej „indeksu”, jeśli będziesz chciał przebudować swój układ XML.

broot
źródło
Czy muszę usunąć fragment, czy też fragment też zostanie usunięty?
K - Toksyczność SO rośnie.
3
@KarlMorrison To pytanie ma prawie 4 lata i nie ma nic wspólnego z fragmentami. Proponuję zgłosić nowe pytanie i / lub przyjrzeć się android.app.FragmentTransactionjego replace()metodzie.
lupz
Szkoda, że ​​twoja odpowiedź jest zbyt złożona - w komentarzach - dla początkujących programistów Androida :-(
Antonio Sesto
2
@AntonioSesto co jest zbyt skomplikowane? Gdzie się pomyliłeś?
AdamMc331
@broot Chcę codziennie dodawać obrazy do mojego linearnego układu, który zrobiłem. później usuwam niektóre obrazy z układu. następnie chcę przywrócić go na jego miejscu, z którego usunąłem. oznacza, że ​​chcę dodawać obrazy bez usuwania rodzica dziecka, czy możesz mnie zawstydzić?
PriyankaChauhan
43

Jeśli robisz to bardzo często, możesz użyć ViewSwitcher lub ViewFlipper, aby ułatwić zastępowanie widoku.

Snicolas
źródło
Tak, jeśli jest kwestia alternatywnych widoków, to widok flipper / switcher jest lepszy w użyciu
Zoombie
2
@Shail Adi, czy próbowałeś gooleć kod samouczka ViewSwitcher?
Snicolas
Wiem, że to jest stare - ale zastrzeżeniem jest to, że ViewSwitcher inicjuje i przechowuje oba widoki w sobie (FrameLayout).
Vikram Bodicherla
To powinna być zalecana odpowiedź. Dlaczego nie skorzystać po prostu z gotowego, dobrze przetestowanego rozwiązania.
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);
    }
Kaiwalya Rangle
źródło
6
Chociaż ten kod może odpowiedzieć na pytanie, dostarczenie dodatkowego kontekstu dotyczącego tego, jak i / lub dlaczego rozwiązuje problem, poprawiłoby długoterminową wartość odpowiedzi
frobinsonj
0

działa w moim przypadku, oldSensor i newSnsor - oldView i 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);
        }
ch13mob
źródło