26

我有一个带有许多嵌套 LinearLayouts 和 TextViewss 的 LinearLayout

我的主要活动使主要的 LinearLayout 膨胀,

然后我从服务器加载数据并根据接收到的数据,在占位符中添加多个布局(线性布局)

这是一个简单的新闻页面,我在其中加载与新闻关联的图像并将其放置在最初为空的 LinearLayout 中。

每个图像都有以下信息:Title(TextView)、Date(TextView)、Image(ImageView) 所以我实际做的是以下内容:

*请注意,这只是我将所有 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

      }
}

上面的代码适用于单个图像

但是对于多个图像,图像加载器不起作用我猜这是因为所有 ImageViews(多次膨胀)具有相同的 ID

4

4 回答 4

38

当您提供要用作父级的 ViewGroup 时,返回的 Viewinflate()是这个父级(vg在您的情况下),而不是新创建的 View。因此,v指向 ViewGroupvg而不是指向新创建的 View 并且由于您所有的孩子都具有相同的 ,因此每次都返回id相同的子视图(imv, dt, )。ttl

两种解决方案。第一个是id在你完成它们之后,在下一次迭代之前改变它们。因此,在下一次迭代开始的下一次创建中,新创建的 View 将具有与旧 View 不同的 ID,因为它们仍将使用 中定义的旧常量R

另一种解决方案是将参数 false 添加到对 inflate() 的调用中,以便新创建的视图不会附加到 ViewGroup,然后由 inflate() 函数而不是 ViewGroup 返回。然后,您的其余代码将照常工作,但您必须在迭代结束时将它们附加到 ViewGroup。

请注意,您仍然需要提供 ViewGroup,因为它将用于确定 LayoutParams 的值。

于 2013-02-03T06:03:59.650 回答
22

我遇到了同样的问题,根据@SylvainL 的回答,这是一个可行的解决方案:

// 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);
于 2014-01-14T11:07:55.907 回答
9

布局 XML 中的 ImageView 需要有 ID 是否有原因?您能否从 image_preview.xml 布局中删除 android:id 属性,然后简单地遍历膨胀的 LinearLayout 的子级?例如:

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);
于 2013-02-03T01:59:51.403 回答
0

我用动态扩展 XML 布局并获取 id 文本

  private val onAddView = View.OnClickListener {
    val parent = viewForm.findViewById<LinearLayout>(R.id.layout_parent)
    LayoutInflater.from(activity).inflate(R.layout.layout_child, parent) // layout_child has id "tv_attribute"
  }

  private val onSave = View.OnClickListener {
    val parent = viewForm.findViewById<LinearLayout>(R.id.layout_parent)
    for (i in 0 until parent.childCount) {
        val getText = parent.getChildAt(i).findViewById<TextView>(R.id.tv_attribute).text
    }
  }
于 2020-12-03T05:41:27.610 回答