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获取视图。您可以检查-@VedPrakashfindViewById
不是一个静态方法。您不能调用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());