如何以编程方式将ID分配给视图?

在XML文件中,我们可以将ID分配给像android:id="@+id/something"这样的视图,然后调用findViewById(),但是当以编程方式创建视图时,如何分配ID呢?

我认为setId()与默认赋值不同。setId()是额外的。

有人能纠正我吗?

151804 次浏览

是的,你可以在任何视图中用你喜欢的任何(正)整数值调用setId(value),然后使用findViewById(value)在父容器中找到它。注意,对于不同的兄弟视图,用相同的值调用setId()是有效的,但是findViewById()只会返回第一个。

你可以用View.setId(integer)来做这个。在XML中,即使你设置了String id,它也会转换成整数。因此,你可以使用任何(正的)Integer作为你通过编程方式添加的Views

根据View文档

标识符在视图的层次结构中不必是唯一的。 标识符应该是一个正数

所以你可以用任何你喜欢的正整数,但是在这里 可以是一些具有等效id的视图。如果你想找一些 视图在层次结构中调用setTag与一些关键对象可能 方便。< / p >

感谢这个答案

Android id概述

Android id是一个整数,通常用于标识视图;这个id可以通过XML(如果可能的话)和通过代码(以编程方式)赋值。id对于获取由Inflater生成的xml定义的Views的引用(例如通过使用setContentView)最有用。

通过XML分配id

  • 向视图添加__abc0someename__abc1属性。
  • 当构建应用程序时,android:id将被分配一个独特的 int以在代码中使用。
  • 在代码中使用“R.id.somename”引用android:idint值(实际上是一个常量)。
  • 这个int可以在不同版本中改变也就是不要复制id from gen/package.name/R.java,只需使用"R.id.somename"。
  • (同样,在XML中分配给PreferenceidPreference生成它的View时不会被使用。)

通过代码分配id(以编程方式)

  • 使用someView.setId(int);手动设置ids
  • int必须是正的,但在其他方面是任意的——它可以是你想要的任何东西(如果这是可怕的,请继续阅读)。
  • 例如,如果创建和编号几个表示项目的视图,您可以使用它们的项目编号。

ids的唯一性

  • XML-assigned的__abc1将是唯一的。
  • 代码分配的__abc0必须是唯一的
  • 代码赋值的__abc0(理论上)可能与__abc1赋值的__abc0冲突。
  • 如果正确查询(继续阅读),这些冲突的__abc0将无关紧要。

什么时候(以及为什么)发生冲突的__abc并不重要

  • findViewById(int)将通过视图层次结构从您指定的视图递归地迭代深度优先,并返回它找到的第一个带有匹配idView
  • 只要在层次结构中xml定义的id之前没有分配代码赋值的idfindViewById(R.id.somename)将始终返回xml定义的视图,因此__abc0d。

动态创建视图并分配__abc

  • 在布局XML中,用id定义一个空的ViewGroup
  • 例如带有android:id="@+id/placeholder"LinearLayout
  • 使用代码用__abc1填充占位符ViewGroup
  • 如果你需要或想要,为每个视图分配任何方便的__abc。
  • 使用placeholder.findViewById(convenience int)查询这些子视图;

  • API 17引入了View.generateViewId(),它允许你生成唯一的ID。

如果你选择保留对你的观点的引用,请确保用getApplicationContext()实例化它们,并确保在onDestroy中将每个引用设置为空。显然泄漏 Activity(在is被销毁后挂在它上)是浪费的..:)

保留XML android:id在代码中使用

API 17介绍 View.generateViewId() 生成一个唯一的ID。(感谢take- opportunities -make-changes指出这一点。

如果你的ViewGroup不能通过XML定义(或者你不希望它是),你可以通过XML保留id,以确保它保持唯一:

这里,values/ids.xml定义了一个自定义id:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="reservedNamedId" type="id"/>
</resources>

一旦创建了ViewGroup或View,就可以附加自定义id

myViewGroup.setId(R.id.reservedNamedId);

冲突的id例子

为了让例子更清晰,让我们来看看在幕后发生id冲突时会发生什么。

布局/ mylayout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/placeholder"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>

为了模拟冲突,假设我们的最新构建为__ABC0(__ABC1)分配了一个int 12 . .

接下来,MyActivity.java以编程方式(通过代码)定义了一些添加视图:

int placeholderId = R.id.placeholder; // placeholderId==12
// returns *placeholder* which has id==12:
ViewGroup placeholder = (ViewGroup)this.findViewById(placeholderId);
for (int i=0; i<20; i++){
TextView tv = new TextView(this.getApplicationContext());
// One new TextView will also be assigned an id==12:
tv.setId(i);
placeholder.addView(tv);
}

所以placeholder和一个新的__abc1都有一个12的id !但如果我们查询占位符的子视图,这不是真正的问题:

// Will return a generated TextView:
placeholder.findViewById(12);


// Whereas this will return the ViewGroup *placeholder*;
// as long as its R.id remains 12:
Activity.this.findViewById(12);

*还不错