Cómo inflar varias instancias de un diseño con el mismo id dentro de un diseño inflado


Tengo un LinearLayout con muchos LinearLayouts anidados y TextViewss

Mi actividad principal infla la distribución lineal principal,

Luego cargo los datos de un servidor y, en función de los datos recibidos, agrego múltiples diseños en un titular de lugar (LinearLayout)

Esto es simple una página de noticias donde cargo Imágenes asociadas con las noticias y las coloco dentro de un LinearLayout inicialmente vacío.

Cada imagen tiene la siguiente información: Título (TextView), Fecha (TextView), Imagen (ImageView) así que lo que realmente hago es lo siguiente:

*Tenga en cuenta que esto es solo el esencial codificado en la pregunta I elemenated todos los try -> catch ... if/else ....etc

public void addImages(JSONArray images){
      ViewGroup vg = (ViewGroup) findViewById(R.id.imagesPlaceHolder);


      // loop on images
      for(int i =0;i<images.length;i++){

          View v = getLayoutInflater().inflate(R.layout.image_preview,vg);
          // then 
          I think that here is the problem 
          ImageView imv = (ImageView) v.findViewById(R.id.imagePreview);
          TextView dt = (TextView) v.findViewById(R.id.dateHolder);
          TextView ttl = (TextView) v.findViewById(R.id.title);
          // then 
          dt.setText("blablabla");
          ttl.setText("another blablabla");
          // I think the problem is here too, since it's referring to a single image
          imv.setTag( images.getJSONObject(i).getString("image_path").toString() );
          // then Image Loader From Server or Cache to the Image View

      }
}

El código anterior funciona bien para una sola imagen

Pero para varias imágenes el Cargador de imágenes no funciona, supongo que es porque todas las ImageViews (infladas varias veces) tienen el mismo ID

Author: Shehabic, 2013-02-03

3 answers

¿Hay alguna razón por la que ImageView en el XML de diseño necesita tener un ID? ¿Podría borrar los atributos android:id de image_preview?diseño xml y luego simplemente iterar a través de los hijos de la inflada LinearLayout? Por ejemplo:

ViewGroup v = (ViewGroup)getLayoutInflater().inflate(R.layout.image_preview,vg);
ImageView imv = (ImageView) v.getChildAt(0);    
TextView dt = (TextView) v.getChildAt(1);
TextView ttl = (TextView) v.getChildAt(2);
 9
Author: user697495,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-03 01:59:51

Cuando proporciona un ViewGroup para ser utilizado como el padre, la vista devuelta por inflate() es este padre (vg en su caso) y no la Vista recién creada. Por lo tanto, v apunta hacia el ViewGroup vg y no hacia la Vista recién creada y como todos sus hijos tienen el mismo id, las mismas subviews (imv, dt, ttl) se devuelven cada vez.

Dos soluciones. El primero es cambiar su id justo después de que haya terminado con ellos, antes de la siguiente iteración. Por lo tanto, en la siguiente creación al comienzo de la siguiente iteración, las vistas recién creadas tendrán un ID diferente de las vistas anteriores porque seguirán utilizando la constante antigua definida en R.

La otra solución sería agregar el parámetro false a la llamada a inflate() para que la vista recién creada no se adjunte a ViewGroup y luego sea devuelta por la función inflate() en lugar de ViewGroup. El resto de su código entonces funciona como atendido con la excepción de que tendrá que adjuntarlos al ViewGroup al final de la iteración.

Tenga en cuenta que todavía necesita proporcionar un ViewGroup porque se utilizará para determinar el valor de los LayoutParams.

 31
Author: SylvainL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-03 06:03:59

Tuve el mismo problema, y basado en la respuesta de @SylvainL, aquí hay una solución que funciona:

// myContext is, e.g. the Activity.
// my_item_layout has a TextView with id='text'
// content is the parent view (e.g. your LinearLayoutView)
// false means don't add direct to the root
View inflated = LayoutInflater.from(myContext).inflate(R.layout.my_item_layout, content, false);

// Now, before we attach the view, find the TextView inside the layout.
TextView tv = (TextView) inflated.findViewById(R.id.text);
tv.setText(str);

// now add to the LinearLayoutView.
content.addView(inflated);
 20
Author: Ben Clayton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-14 11:07:55