在一个XML文件,我们可以分配一个ID到一个视图像android: ID ="@+ ID /某物",然后调用findViewById(),但当创建一个视图编程,我如何分配一个ID?
我认为setId()与默认赋值不同。setId()是额外的。
有人能纠正我吗?
在一个XML文件,我们可以分配一个ID到一个视图像android: ID ="@+ ID /某物",然后调用findViewById(),但当创建一个视图编程,我如何分配一个ID?
我认为setId()与默认赋值不同。setId()是额外的。
有人能纠正我吗?
是的,你可以在任何视图中用任何(正)整数值调用setId(value),然后使用findViewById(value)在父容器中找到它。注意,对于不同的兄弟视图,用相同的值调用setId()是有效的,但是findViewById()将只返回第一个。
你可以使用View.setId(integer)。在XML中,即使你设置了String id,它也会转换成整数。因此,您可以为以编程方式添加的视图使用任何(正)整数。
根据查看文档 标识符在这个视图的层次结构中不必是唯一的。 标识符应该是一个正数。 所以你可以用任何你喜欢的正整数,但是在这里 可以是一些具有等效id的视图。如果你想找一些 视图在层次结构中调用setTag与一些关键对象可能 方便。
这要归功于这个答案。
Android id概述
Android id是一个整数,通常用于识别视图;这个id可以通过XML(如果可能)和代码(以编程方式)分配。id对于获取由Inflater生成的xml定义视图的引用(例如使用setContentView)最有用。
通过XML分配id
添加一个属性android:id="@+id/ someename "到你的视图。 当你的应用程序构建时,android:id将被分配一个唯一的int在代码中使用。 在代码中使用"R.id. id "引用android:id的int值。Somename”(实际上是一个常量。) 这个int可以在不同的版本中改变,所以不要从gen/package.name/R.java中复制id,只需使用“R.id.somename”即可。 (同样,当首选项生成其视图时,XML中分配给首选项的id是不使用的。)
通过代码分配id(以编程方式)
使用someView.setId(int)手动设置id; int必须是正的,但在其他方面是任意的-它可以是任何你想要的(如果这是可怕的,请继续阅读)。 例如,如果创建和编号几个表示项目的视图,您可以使用它们的项目编号。
id的唯一性
xml分配的id将是唯一的。 代码分配的id不必是唯一的 代码分配的id(理论上)可能与xml分配的id冲突。 如果查询正确,这些冲突的id并不重要(请继续阅读)。
什么时候(以及为什么)有冲突的id并不重要
findViewById(int)将从您指定的视图递归地遍历视图层次结构的深度优先,并返回它找到的带有匹配id的第一个视图。 只要在层次结构中xml定义的id之前没有分配代码赋值的id, findViewById(R.id.somename)将始终返回这样标识的xml定义的视图。
动态创建视图和分配id
在布局XML中,定义一个带id的空ViewGroup。 例如带有android:id="@+id/占位符"的LinearLayout。 使用代码用视图填充占位符ViewGroup。 如果需要或想要,可以为每个视图分配任何方便的id。 使用placeholder.findViewById(convenience int)查询这些子视图; API 17引入了View.generateViewId(),它允许你生成一个唯一的ID。
如果您选择保留对视图的引用,请确保使用getApplicationContext()实例化它们,并确保在onDestroy中将每个引用设置为空。显然泄露活动(挂在它被摧毁后)是浪费。:)
在代码中保留一个XML android:id
API 17引入了View.generateViewId(),它生成一个唯一的ID。(感谢risk -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>
为了模拟冲突,假设我们的最新构建为R.id.placeholder(@+id/placeholder)分配了一个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);
}
所以占位符和一个新的TextViews都有一个id为12!但如果我们查询占位符的子视图,这不是真正的问题:
// 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);
*还不错