【问题标题】:How to inflate multiple instances of a layout with the same id inside an inflated layout如何在膨胀的布局中膨胀具有相同 id 的布局的多个实例
【发布时间】:2013-02-03 01:14:49
【问题描述】:

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

我的主要活动膨胀了主要的 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

      }
}

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

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

【问题讨论】:

  • 您有什么理由不使用列表视图吗?
  • 是的,我在 Scrollview 中有一个 LinearLayout,顶部有一些 TextView,然后我有很多 ImageView,甚至是 Video Holders,ListView 将在 ScrollView 中有自己的滚动,它会不利于可用性(如果我是对的)

标签: android android-layout android-view android-inflate


【解决方案1】:

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

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

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

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

【讨论】:

  • 好吧,我上面的解决方案有效,但我担心的是:我怎么知道在我使用的 1001 到 1000+x 或 2001 到2000 + x。我注意到自动生成的 id 通常具有非常大的值。
  • 用 findViewById() 检查它:如果没有具有所需整数值的 ID,它将返回 null。但是,在您的情况下,重要的是值 (1000 + i) 与 R.id.imagePreview 不同。
  • 在迭代结束时更改“id”就可以了……:p 仍然像一个补丁:p
  • @Shehabix 如果你想使用未使用的 ID,View.generateViewId() 就是你要找的。 “生成一个适合在 setId(int) 中使用的值。该值不会与 aapt 为 R.id 在构建时生成的 ID 值冲突。”
  • 如果膨胀相对布局,两种提议的解决方案似乎都不能很好地工作。当 ID 被替换时,相关属性(例如 toRightOf)似乎不起作用。如果指定 true 以在 inflate 时添加到 rootView,布局也会混乱。
【解决方案2】:

我遇到了同样的问题,根据@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);

【讨论】:

    【解决方案3】:

    布局 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);
    

    【讨论】:

    • 是的,我的视图嵌套在
    【解决方案4】:

    我用动态扩展 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
        }
      }
    

    【讨论】:

      猜你喜欢
      • 2017-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-22
      • 1970-01-01
      相关资源
      最近更新 更多