Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inflate multiple instances of a layout with the same id inside an inflated layout

I have a LinearLayout with many nested LinearLayouts and TextViewss

My main activity inflates the main LinearLayout,

Then I load data from a server and based on the data received, I add multiple Layouts in a place holder (LinearLayout)

This is simple a news page where I load Images associated with the news and place it inside an initially empty LinearLayout.

Each Image has the following info: Title(TextView), Date(TextView), Image(ImageView) so what I actually do is the following:

*Please notice that this is only the essential coded in the question I elemenated all the 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

      }
}

The code above works good for a single image

But for multiple images the Image Loader doesn't work I guess it's because all ImageViews (Inflated multiple times) have the same ID

like image 213
Shehabic Avatar asked Feb 03 '13 01:02

Shehabic


2 Answers

When you provide a ViewGroup to be used as the parent, the View returned by inflate() is this parent (vg in your case) and not the newly created View. Therefore, v points toward the ViewGroup vg and not toward the newly created View and as all of your children have the same id, the same subviews (imv, dt, ttl) are returned each time.

Two solutions. The first one is to change their id right after you are finished with them, before the next iteration. Therefore, on the next creation at the beginning of the next iteration, the newly created Views will have a different IDs from the older Views because they will still use the old constant defined in R.

The other solution would be to add the parameter false to the call to inflate() so that the newly created view will not be attached to the ViewGroup and will then be returned by the inflate() function instead of the ViewGroup. The rest of your code will then works as attended with the exception that you will have to attach them to the ViewGroup at the end of the iteration.

Notice that you still need to provide a ViewGroup because it will be used to determine the value of the LayoutParams.

like image 104
SylvainL Avatar answered Nov 03 '22 14:11

SylvainL


I had the same problem, and based on the answer from @SylvainL, here'a a working solution:

// 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);
like image 22
Ben Clayton Avatar answered Nov 03 '22 15:11

Ben Clayton