2012-04-02 9 views
20

W mojej aktywności w systemie Android muszę dynamicznie dodawać pojedynczy widok (w czasie wykonywania) na określonej pozycji w układzie. Dodawany widok jest określany w czasie wykonywania. Na przykład układ może wyglądać mniej więcej tak:Element zastępczy układu Android dla dynamicznie dodawanego widoku

<LinearLayout ...> 
    <TextView ... /> 
    <!-- Dynamic item to be added here --> 
    <TextView ... /> 
</LinearLayout> 

Jaki jest najlepszy sposób, aby to osiągnąć?

Jednym z rozwiązań jest użycie layout.addView(view, index), ale wolę nie kodować indeksu.

Innym rozwiązaniem jest użycie FrameLayout jako miejsce, a miejsce może dynamiczny widok wewnątrz FrameLayout, na przykład:

<LinearLayout ...> 
    <TextView ... /> 
    <FrameLayout android:id="@+id/placeholder" /> 
    <TextView ... /> 
</LinearLayout> 

wówczas:

findViewById(R.id.placeholder).addView(view); 

Jednak to dodaje niepotrzebne widok w hierarchii.

Jaki byłby zalecany sposób, aby to zrobić?

Odpowiedz

13

Myślę, że używanie FrameLayout jako symbolu zastępczego dla widoku "dodanego w czasie wykonywania" jest dobrym rozwiązaniem.

Nie martwiłbym się o wpływ dodatkowego "niepotrzebnego" widoku na wydajność.

+1

Dzięki. Skończyło się na użyciu 'findViewById (R.id.placeholder) .addView (view);', gdzie symbol zastępczy może być FrameLayout lub dowolnym innym układem, jeśli widok powinien być dodany na końcu, na przykład ScrollView. – Ralf

+0

możesz uzyskać głębokie drzewo zagnieżdżonych widoków w ten sposób, co może powodować w niektórych przypadkach stuckoverflowerror, ze względu na ograniczony stack dla wątku UI –

7

Możesz także uzyskać to zachowanie "leniwego", używając ViewStub, jak opisano w tym (raczej starym) article od programistów aplikacji na Androida.

+1

Dla "leniwego włączenia" musisz określić plik układu, który ma zawierać w czasie kompilacji, ale muszę mieć możliwość dodania jednego z wielu widoków (określanych w czasie wykonywania). Zmieniłem to pytanie, by wyjaśnić. – Ralf

+1

Plik układu określony w ViewStub może być pusty LinearLayout, RelativeLayout, ... WhateverLayout, który może być dynamicznie wypełniany dowolną liczbą .AddView(). Nie widzę powodu, dla którego to nie zadziałałoby, jak wspomniałeś powyżej (aktualnie implementuję to teraz) – samosaris

+2

ViewStub stub = (ViewStub) findViewById (R.id.container_stub); stub.setLayoutResource (R.layout.activity_home); – frostymarvelous

1

Możesz użyć addView (Zobacz dziecko, indeks int) bez twardego kodowania dokładnego indeksu.

Jeśli jeden z sąsiadów widoku może zostać naprawiony (na przykład przed miejscem, w którym chcesz wstawić element, znajduje się określona etykieta), możesz uzyskać indeks tego widoku, a następnie wstawić widok dynamiczny:

View previousView = findViewById(ID_OF_PREVIOUS_VIEW); 
ViewGroup parent = (ViewGroup)previousView.getParent(); 
int previousIndex = parent.indexOfChild(previousView); 
parent.addView(theDynamicallyCreatedView, previousIndex + 1); 

Albo można użyć ViewStub, ale zamiast napełniania układu, po prostu usuń go:

View placeholder = findViewById(ID_OF_STUB); 
ViewGroup parent = (ViewGroup)previousView.getParent(); 
int index = parent.indexOfChild (placeholder); 
parent.removeViewAt(index); 
parent.addView(theDynamicallyCreatedView, index); 

ten sposób nie skończy się z ogromnym hierarchii widoku.

Powiązane problemy