Cómo inflar una vista con un diseño

221

Tengo un diseño definido en XML. Contiene también:

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

Me gustaría inflar este RelativeView con otro archivo de diseño XML. Puedo usar diferentes diseños según la situación. ¿Cómo debería hacerlo? Estaba probando diferentes variaciones de

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

Pero ninguno de ellos funcionó bien.

Michal Dymel
fuente

Respuestas:

390

No estoy seguro de haber seguido su pregunta: ¿está intentando adjuntar una vista secundaria a RelativeLayout? Si es así, quiere hacer algo en la línea de:

RelativeLayout item = (RelativeLayout)findViewById(R.id.item);
View child = getLayoutInflater().inflate(R.layout.child, null);
item.addView(child);
Graeme Duncan
fuente
3
Recibo un error: 02-25 22: 21: 19.324: ERROR / AndroidRuntime (865): Causado por: java.lang.IllegalStateException: El niño especificado ya tiene un padre. Primero debe llamar a removeView () en el padre del niño.
Michal Dymel
27
Acabo de probar esto ahora, necesitaba: Ver child = getLayoutInflater (). Inflate (R.layout.child, null);
James
3
El problema no es el código. Es bastante fácil seguir el código. ¿Dónde haces el archivo xml? ¿Es el tipo un recurso de estilo de tema? el problema que creo que la gente que
incluí
15
Esto no es perfecto Se debe usar la versión de 3 param del inflador; este es el motivo: doubleencore.com/2013/05/layout-inflation-as-intended
Nick Cardoso
3
La respuesta es incorrecta, incluso si funciona. Por favor, consulte esta publicación posiblemobile.com/2013/05/layout-inflation-as-intended
ARK
107

Inflas un recurso XML. Ver el documento LayoutInflater .

Si su diseño está en mylayout.xml , haría algo como:

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);
ccheneson
fuente
44
Tengo mi vista principal inflada. El problema es que quiero inflar parte de él desde otro archivo XML. Este elemento RelativeLayout es parte de un diseño más grande y quiero llenarlo con el diseño de otro archivo XML.
Michal Dymel
. hum me siento a continuación, no tengo ni idea :( ¿Está utilizando algo así como <include> en la página principal para incluir otra disposición?
ccheneson
No, es un diseño simple. Creo que solo agregaré mis elementos programáticamente, sin XML. ¡Gracias por la ayuda!
Michal Dymel
27

Aunque es una respuesta tardía, pero me gustaría agregar esa única forma de obtener esto

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

donde itemestá el diseño primario donde desea agregar un diseño secundario.

Shaista Naaz
fuente
(incluso más tarde aún) Estoy teniendo dificultades para implementar su respuesta. Probé el código que mencionaste anteriormente, pero reemplacé 'item' por: 'R.layout.activity_layout' Recibo un "No hay ningún método aplicable a '(int, int)'" ¿podría molestarte por tus pensamientos?
Kyle
1
@Kyle, incluso más tarde aún. No puede usar Rrecursos como referencias a un objeto, son solo ints. Debe usar findViewByIdpasarle el Rrecurso, luego escribir emitirlo al objeto deseado. Luego puede usarlo en llamadas a funciones como inflate. (es decir ViewGroup item = (ViewGroup) findViewById(R.layout.activity_layout);... entonces puedes usar itemcomo arriba.)
Pimp Trizkit
Supongo que uso en RelativeLayoutlugar de ViewGroupallí en mi ejemplo anterior, ya que no puede crear una instancia de la clase base ViewGroup. La regla de edición de 5 minutos me consiguió. lol
Pimp Trizkit
¿Es posible ocultar el padre y mostrar solo la vista infantil
NovusMobile
Gracias, este método ayudó cuando no pude usar getContext () en el ejemplo anterior ya que estoy usando fragmentos.
RightHandedMonkey
19

Es útil agregar a esto, aunque sea una publicación anterior, que si la vista secundaria que se está inflando desde xml se va a agregar a un diseño de grupo de vista, debe llamar a inflar con una pista de qué tipo de grupo de vista va a ir para ser agregado a. Me gusta:

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

El método de inflado está bastante sobrecargado y describe esta parte del uso en los documentos. Tuve un problema en el que una sola vista inflada desde xml no se alineaba correctamente en el padre hasta que hice este tipo de cambio.

Maximus
fuente
Finalmente, gracias :) Esto permite agregar múltiples vistas a un solo padre, pero sin la necesidad de preocuparse por los LayoutParams, que se leen desde el XML. ¡Buen trabajo!
Sabo
13

Aún más simple es usar

View child = View.inflate(context, R.layout.child, null)
item.addChild(child) //attach to your item
Ashish Rawat
fuente
El uso View.inflate()es la mejor manera, sin innecesaria LayoutInflatero getSystemService(Context.LAYOUT_INFLATER_SERVICE)o cualquiera de todo lo que molestia! : D
varun
8

inflación de diseño

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

Si no está en una actividad, puede usar el from()método estático de la LayoutInflaterclase para obtener un LayoutInflater, o solicitar el servicio también del método de contexto 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);

(Sé que hace casi 4 años, pero aún vale la pena mencionarlo)

Juan cortés
fuente
4

Si desea agregar una sola vista varias veces, entonces debe usar

   layoutInflaterForButton = getActivity().getLayoutInflater();

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

Si te gusta

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

y

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

entonces arrojará la excepción de toda la vista lista agregada.

John Smith
fuente
4

AttachToRoot establecido en True

Solo piense que especificamos un botón en un archivo de diseño XML con su ancho de diseño y altura de diseño establecidos para emparejar_parente.

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

En este botón, haga clic en Evento. Podemos establecer el siguiente código para inflar el diseño en esta actividad.

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

Espero que esta solución funcione para ti.

Equipo eSparkBiz
fuente
3

Prueba este código:

  1. Si solo quieres inflar tu diseño:

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. Si desea inflar su diseño en contenedor (diseño principal):

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.

Rohit Mhatre
fuente
2

Tuve el momento más difícil con este error, debido a mis circunstancias únicas, pero finalmente encontré una solución.

Mi situación: estoy usando una vista separada (XML) que contiene una WebView, luego se abre en una AlertDialogcuando hago clic en un botón en mi vista de actividad principal. Pero de una forma u otra WebViewpertenecía a la vista de actividad principal (probablemente porque saqué el recurso de aquí), así que justo antes de asignarlo a mi AlertDialog(como una vista), tuve que obtener el padre de mi WebView, ponerlo en un ViewGroup, luego elimine todas las vistas sobre eso ViewGroup. Esto funcionó y mi error desapareció.

// 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...

... más tarde, después de cargar mi 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();
Azurespot
fuente
2

Si está intentando adjuntar una vista secundaria a RelativeLayout? puedes hacer siguiendo

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

Con Kotlin, puedes usar:

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

[your_main_layout].apply {
    //..
    addView(content)
}
Hasan A Yousef
fuente
-1

Había usado el siguiente fragmento de código para esto y funcionó para mí.

LinearLayout linearLayout = (LinearLayout)findViewById(R.id.item);
View child = getLayoutInflater().inflate(R.layout.child, null);
linearLayout.addView(child);
SFDCCoder
fuente