Jak napompować jeden widok za pomocą układu


221

Mam układ zdefiniowany w XML. Zawiera także:

<RelativeLayout
    android:id="@+id/item"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
/>

Chciałbym napompować ten RelativeView innym plikiem pliku XML. Mogę używać różnych układów w zależności od sytuacji. Jak mam to zrobić? Próbowałem różnych odmian

RelativeLayout item = (RelativeLayout) findViewById(R.id.item);
item.inflate(...)

Ale żaden z nich nie działał dobrze.

Odpowiedzi:


390

Nie jestem pewien, czy śledziłem twoje pytanie - czy próbujesz dołączyć widok dziecka do RelativeLayout? Jeśli tak, chcesz zrobić coś w stylu:

RelativeLayout item = (RelativeLayout)findViewById(R.id.item);
View child = getLayoutInflater().inflate(R.layout.child, null);
item.addView(child);

3
Pojawia się błąd: 02-25 22: 21: 19.324: ERROR / AndroidRuntime (865): Przyczyna: java.lang.IllegalStateException: Określone dziecko ma już element nadrzędny. Najpierw musisz wywołać removeView () na rodzicu dziecka.
Michał Dymel,

27
Właśnie próbowałem tego teraz, potrzebowałem: View child = getLayoutInflater (). Inflate (R.layout.child, null);
James

3
Problemem nie jest kod. Kod jest dość łatwy do śledzenia. Gdzie tworzysz plik xml. czy typ jest zasobem stylu motywu? Problem, o którym myślę, że uwzględnili mnie ludzie, to gdzie umieszczamy ten plik XML
Lpc_dark

15
To nie jest idealne. Należy użyć 3-paramowej wersji inflatora - oto dlaczego: doubleencore.com/2013/05/layout-inflation-as-intended
Nick Cardoso

3
Odpowiedź jest niepoprawna, nawet jeśli działa. Proszę sprawdzić ten post possiblemobile.com/2013/05/layout-inflation-as-intended
ARK

107

Nadmuchujesz zasób XML. Zobacz dokument LayoutInflater .

Jeśli twój układ znajduje się w pliku mylayout.xml , zrobiłbyś coś takiego:

View view; 
LayoutInflater inflater = (LayoutInflater)   getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
view = inflater.inflate(R.layout.mylayout, null);

RelativeLayout item = (RelativeLayout) view.findViewById(R.id.item);

4
Mój główny widok jest zawyżony. Problem polega na tym, że chcę nadmuchać jego część z innego pliku XML. Ten element RelativeLayout jest częścią większego układu i chcę go wypełnić układem z innego pliku XML.
Michał Dymel,

przykre, przepraszam, nie mam pojęcia :(. Czy używasz w swoim głównym widoku czegoś takiego jak <include>, aby uwzględnić inny układ?
ccheneson

Nie, to prosty układ. Myślę, że po prostu dodam moje elementy programowo - bez XML. Dzięki za pomoc!
Michał Dymel,

27

Chociaż późna odpowiedź, ale chciałbym dodać ten jeden sposób na uzyskanie tego

LayoutInflater layoutInflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = layoutInflater.inflate(R.layout.mylayout, item );

gdzie itemjest układ nadrzędny, do którego chcesz dodać układ podrzędny.


(jeszcze później) Mam problem z implementacją twojej odpowiedzi. Wypróbowałem kod, o którym wspomniałeś powyżej, ale zastąpiłem „item”: „R.layout.activity_layout” Dostaję komunikat „Nie ma odpowiedniej metody na” (int, int) ”„ czy mogę sprawić ci kłopot za twoje przemyślenia?
Kyle

1
@Kyle - jeszcze później. Nie możesz używać Rzasobów jako odniesień do obiektu, są to po prostu ints. Musisz użyć findViewByIdprzekazując go do Rzasobu, a następnie wpisz rzutuj na wybrany obiekt. Następnie możesz użyć go w wywołaniach funkcji, takich jak inflate. (tzn. ViewGroup item = (ViewGroup) findViewById(R.layout.activity_layout);... możesz użyć itemjak wyżej.)
Pimp Trizkit

Myślę, że mam zamiar użyć RelativeLayoutzamiast tego ViewGroupw powyższym przykładzie, ponieważ nie można utworzyć instancji klasy podstawowej ViewGroup. Dopadła mnie zasada edycji 5 minut. lol
Pimp Trizkit

Czy można ukryć widok rodzica i wyświetlić tylko widok potomny
NovusMobile

Dzięki, ta metoda pomogła, gdy nie mogłem użyć metody getContext () w poprzednim przykładzie, ponieważ używam fragmentów.
RightHandedMonkey

19

Pomocne jest dodanie do tego, nawet jeśli jest to stary post, że jeśli widok potomny, który jest zawyżany z xml, ma zostać dodany do układu grupy widokowej, musisz wywołać inflate ze wskazówką, jaki rodzaj grupy widokowej ma zamiar do dodania do. Lubić:

View child = getLayoutInflater().inflate(R.layout.child, item, false);

Metoda inflacji jest dość przeciążona i opisuje tę część użycia w dokumentach. Miałem problem polegający na tym, że pojedynczy widok zawyżony z xml nie wyrównywał się prawidłowo w obiekcie nadrzędnym, dopóki nie wprowadziłem tego typu zmian.


Na koniec dziękuję :) Pozwala to dodać wiele widoków do jednego rodzica, ale bez potrzeby martwienia się o LayoutParams - które są odczytywane z XML. Dobra robota!
Sabo

13

Jeszcze prostszym sposobem jest użycie

View child = View.inflate(context, R.layout.child, null)
item.addChild(child) //attach to your item

Korzystanie View.inflate()jest najlepszy sposób, bez zbędnych LayoutInflaterlub getSystemService(Context.LAYOUT_INFLATER_SERVICE)lub którykolwiek z całej tej uciążliwości! : D
varun

8

inflacja układu

View view = null;
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
view = inflater.inflate(R.layout.mylayout, null);
main.addView(view);

6

Jeśli nie jesteś zajęty, możesz użyć from()metody statycznej z LayoutInflaterklasy, aby uzyskać LayoutInflater, lub zażądać usługi z metody kontekstowej getSystemService():

LayoutInflater i;
Context x;       //Assuming here that x is a valid context, not null

i = (LayoutInflater) x.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//OR
i = LayoutInflater.from(x);

(Wiem, że to prawie 4 lata temu, ale nadal warto o tym wspomnieć)


4

Jeśli chcesz dodać jeden widok wiele razy, musisz użyć

   layoutInflaterForButton = getActivity().getLayoutInflater();

 for (int noOfButton = 0; noOfButton < 5; noOfButton++) {
        FrameLayout btnView = (FrameLayout) layoutInflaterForButton.inflate(R.layout.poll_button, null);
        btnContainer.addView(btnView);
    }

Jeśli ci się podoba

   layoutInflaterForButton = getActivity().getLayoutInflater();
    FrameLayout btnView = (FrameLayout) layoutInflaterForButton.inflate(R.layout.poll_button, null);

i

for (int noOfButton = 0; noOfButton < 5; noOfButton++) {
            btnContainer.addView(btnView);
        }

wtedy wyrzuci wyjątek od wszystkich gotowych dodanych widoków.


4

AttachToRoot Ustaw na True

Pomyśl tylko, że podaliśmy przycisk w pliku układu XML z szerokością i wysokością układu ustawioną na match_parent.

<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/custom_button">
</Button>

Na tych przyciskach kliknij wydarzenie, które możemy ustawić zgodnie z kodem, aby nadmuchać układ w tej aktywności.

LayoutInflater inflater = LayoutInflater.from(getContext());
inflater.inflate(R.layout.yourlayoutname, this);

Mam nadzieję, że to rozwiązanie działa dla Ciebie.!


3

Wypróbuj ten kod:

  1. Jeśli chcesz po prostu zawęzić układ:

View view = LayoutInflater.from(context).inflate(R.layout.your_xml_layout,null); // Code for inflating xml layout
RelativeLayout item = view.findViewById(R.id.item);   

  1. Jeśli chcesz zawyżać swój układ w kontenerze (układ nadrzędny):

LinearLayout parent = findViewById(R.id.container);        //parent layout.
View view = LayoutInflater.from(context).inflate(R.layout.your_xml_layout,parent,false); 
RelativeLayout item = view.findViewById(R.id.item);       //initialize layout & By this you can also perform any event.
parent.addView(view);             //adding your inflated layout in parent layout.


2

Najtrudniej mi było z tym błędem z powodu moich wyjątkowych okoliczności, ale w końcu znalazłem rozwiązanie.

Moja sytuacja: używam osobnego widoku (XML), który zawiera a WebView, a następnie otwiera się AlertDialogpo kliknięciu przycisku w głównym widoku aktywności. Ale jakoś czy inaczej WebViewnależała do głównego widoku działalności (prawdopodobnie dlatego, że ciągnąć zasób stąd), a więc tuż przed I przypisany do mojego AlertDialog(w widoku), musiałem dostać rodzica z moich WebView, włożyć do ViewGroup, następnie usuń wszystkie widoki na ten temat ViewGroup. To zadziałało, a mój błąd zniknął.

// set up Alert Dialog box
AlertDialog.Builder alert = new AlertDialog.Builder(this);
// inflate other xml where WebView is
LayoutInflater layoutInflater = (LayoutInflater)this.getSystemService
                (Context.LAYOUT_INFLATER_SERVICE);
View v = layoutInflater.inflate(R.layout.your_webview_layout, null);
final WebView webView = (WebView) v.findViewById(R.id.your_webview_id);

// more code...

.... później po załadowaniu mojego WebView....

// first, remove the parent of WebView from it's old parent so can be assigned a new one.
ViewGroup vg = (ViewGroup) webView.getParent();
vg.removeAllViews();

// put WebView in Dialog box
alert.setView(webView);
alert.show();

2

Jeśli próbujesz dołączyć widok podrzędny do RelativeLayout? możesz to zrobić, wykonując następujące czynności

RelativeLayout item = (RelativeLayout)findViewById(R.id.item);
View child = getLayoutInflater().inflate(R.layout.child, item, true);

1

Dzięki Kotlin możesz używać:

val content = LayoutInflater.from(context).inflate(R.layout.[custom_layout_name], null)

[your_main_layout].apply {
    //..
    addView(content)
}

-1

Użyłem do tego fragmentu kodu i zadziałało to dla mnie.

LinearLayout linearLayout = (LinearLayout)findViewById(R.id.item);
View child = getLayoutInflater().inflate(R.layout.child, null);
linearLayout.addView(child);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.