Java 如何为动态创建的视图分配唯一ID?

Java 如何为动态创建的视图分配唯一ID?,java,android,xml,Java,Android,Xml,在我的应用程序中,我正在动态创建视图——在本例中是一个编辑文本。但是我添加的每个视图都需要一个唯一的id EditText editText = new EditText(context); LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); editText.setLayoutParams(params); // Which value am I suppo

在我的应用程序中,我正在动态创建
视图
——在本例中是一个
编辑文本
。但是我添加的每个
视图都需要一个唯一的id

EditText editText = new EditText(context);
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
editText.setLayoutParams(params);

// Which value am I supposed to use here?
editText.setId(value);

layout.addView(editText);
如果我分配了一个随机值,我担心会发生冲突,我想不出任何方法来生成没有冲突可能性的ID

请不要告诉我,我知道可以在res/values/ids.xml中定义一组固定的ID,但这不是我想要的!我需要动态创建ID!我不知道我需要多少


那么有没有安全的方法来生成ID呢?

有多种方法可以可靠地为
视图生成ID。有些可用于在运行时动态生成ID,另一些可用于静态定义固定数量的ID。在这个答案中,我将介绍一些解决方案


静态创建固定数量的ID 在res/values中创建一个名为ids.xml的新xml文件,并添加类型为id的元素:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <item name="name" type="id" />     <!-- Creates the id R.id.name -->
    <item name="example" type="id" />  <!-- Creates the id R.id.example -->

</resources>
使用它,您可以动态创建所需的任意多个ID


在API级别17之前动态生成ID 正如@Apoorv所建议的,您可以查看
generateViewId()
的源代码。通过复制代码,我们甚至可以在API级别17之前使用此方法:

private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);

public static int generateViewId() {
    for (; ; ) {
        final int result = sNextGeneratedId.get();

        // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
        int newValue = result + 1;
        if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.

        if (sNextGeneratedId.compareAndSet(result, newValue)) {
            return result;
        }
    }
}
只需将其包含在助手类中,就可以了

通过代码分配
id
(以编程方式)
  • 使用
    someView.setId(
    int
    )手动设置
    id
    s
  • int
    必须是正数,但在其他方面是任意的-它可以是任何你想要的(如果这很糟糕,请继续阅读)
  • 例如,如果创建多个表示项目的视图并对其编号,则可以使用它们的项目编号
通常我们会: 分配id-

另外,

API17
引入了
View.generateView()
,它生成一个唯一的ID

检查:


和。

+1,请看与您的问题类似的内容。@nobalG除了使用id.xml文件的方法外,我还需要一个方法这有什么意义:
View.findViewById(yourView.getId())?您首先需要已经有一个
视图的实例
才能调用
findViewById()
。@XaverKapeller-这不是必需的。
android.view.view
在android软件包中,您可以直接调用它的
findViewById()
,通过它的id获取视图。您可以检查-@VedPrakash
findViewById
不是一个
静态方法。您不能调用
View.findViewById
。你需要一个对象来调用它。我说的是
yourView.getId()
。您在试图获取的
视图
实例上调用
getId()
,显然您已经拥有该实例,不需要再次查找。@Apoorv-
findViewById
是查找具有给定id的子视图的最终公共方法。如果此视图具有给定id,则返回此视图。在developer.android.com/reference/android/View/View.htmltanks中搜索
View.findViewById()
,但除此之外,我还想知道,其中我不必创建预定义的id,因为我不知道将创建多少个。.我添加了一个解决方案来在运行时动态创建id。@XaverKapeller显示了该方法如何生成唯一的id。它可以在API 17之前直接使用,因为它不需要任何特殊的东西吗?只是一个
原子整数
@Apoorv很好,我已经更新了我的答案。这个解决方案比我见过的所有其他方法都好,但我不得不承认这有点可笑,这个方法所做的只是美化递增。这只是其他地方建议的for循环的更好版本。@XaverKapeller是的,我也在想同样的事情。我的意思是,无论更新后的号码是否已经存在,它都不会交叉引用任何地方
private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);

public static int generateViewId() {
    for (; ; ) {
        final int result = sNextGeneratedId.get();

        // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
        int newValue = result + 1;
        if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.

        if (sNextGeneratedId.compareAndSet(result, newValue)) {
            return result;
        }
    }
}
for(int i =0 ; i < yourIDcount ; i++){
    yourView.setId(i);
}
View.findViewById(yourView.getId());