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

发布于 2024-12-20 11:49:48 字数 220 浏览 3 评论 0原文

在 XML 文件中,我们可以为视图分配一个 ID,例如 android:id="@+id/something",然后调用 findViewById(),但是在创建视图时以编程方式查看,如何分配 ID?

我认为 setId() 与默认分配不同。 setId() 是额外的。

有人可以纠正我吗?

In an XML file, we can assign an ID to a view like android:id="@+id/something" and then call findViewById(), but when creating a view programmatically, how do I assign an ID?

I think setId() is not the same as default assignment. setId() is extra.

Can anybody correct me?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

十二 2024-12-27 11:49:48

Android id 概述

Android id 是一个常用于标识视图的整数;此 id 可以通过 XML(如果可能)和代码(以编程方式)分配。id 对于获取 XML 定义的 View 的引用最有用。由 Inflater 生成的 code>(例如使用 setContentView。)

通过 XML 分配 id

  • 添加属性的android:id="@+id/somename" 到您的视图。
  • 构建应用程序时,android:id 将被分配一个unique int 以在代码中使用。
  • 使用“R.id.somename”(实际上是一个常量)在代码中引用您的 android:idint 值。
  • this int 可以在不同的版本中发生变化,因此永远不要从 gen/package.name/R.java 复制 id,只需使用“R.id.somename”。
  • (此外,当 Preference 生成其 View 时,不会使用在 XML 中分配给 Preferenceid。)

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

  • 使用someView.setId(int);手动设置
  • id >int 必须是正数,但否则是任意的 - 它可以是无论你想要什么(如果这很可怕,请继续阅读。)
  • 例如,如果创建并编号多个代表项目的视图,您可以使用它们的项目编号。

id 的唯一性

  • < code>XML 分配的 id 是唯一的。
  • 代码分配的 id不必 必须是唯一的
  • 代码分配的 id 可以(理论上)与 XML-分配的id
  • 如果正确查询,这些冲突的 id 并不重要(继续阅读)。

何时(以及为什么)冲突的 id 并不重要

  • findViewById(int) 将从您指定的视图中以深度优先递归方式遍历视图层次结构 em> 并返回它找到的第一个具有匹配 idView
  • 只要层次结构中 XML 定义的 id 之前没有分配代码分配的 idfindViewById(R.id.somename) 将始终返回 XML 定义的视图,因此 id'd。

动态创建视图并分配 ID

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

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

如果您选择保留对视图的引用,请务必使用 getApplicationContext() 实例化它们,并确保在 onDestroy 中将每个引用设置为 null代码>.显然泄露Activity(在它被销毁后挂在它上面)是浪费的..:)

保留一个XMLandroid:id以在代码中使用

API 17 引入了 View.generateViewId() 它生成一个唯一的 ID。(感谢 take-chances-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 example

为了清楚起见,通过混淆示例的方式,让我们检查一下当幕后发生 id 冲突时会发生什么。

layout/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..

)定义了一些添加视图:

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);
}

接下来,MyActivity.java 以编程方式(通过代码 placeholder 和我们的新产品之一TextViewid 均为 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);

*还不错

Android id overview

An Android id is an integer commonly used to identify views; this id can be assigned via XML (when possible) and via code (programmatically.) The id is most useful for getting references for XML-defined Views generated by an Inflater (such as by using setContentView.)

Assign id via XML

  • Add an attribute of android:id="@+id/somename" to your view.
  • When your application is built, the android:id will be assigned a unique int for use in code.
  • Reference your android:id's int value in code using "R.id.somename" (effectively a constant.)
  • this int can change from build to build so never copy an id from gen/package.name/R.java, just use "R.id.somename".
  • (Also, an id assigned to a Preference in XML is not used when the Preference generates its View.)

Assign id via code (programmatically)

  • Manually set ids using someView.setId(int);
  • The int must be positive, but is otherwise arbitrary- it can be whatever you want (keep reading if this is frightful.)
  • For example, if creating and numbering several views representing items, you could use their item number.

Uniqueness of ids

  • XML-assigned ids will be unique.
  • Code-assigned ids do not have to be unique
  • Code-assigned ids can (theoretically) conflict with XML-assigned ids.
  • These conflicting ids won't matter if queried correctly (keep reading).

When (and why) conflicting ids don't matter

  • findViewById(int) will iterate depth-first recursively through the view hierarchy from the View you specify and return the first View it finds with a matching id.
  • As long as there are no code-assigned ids assigned before an XML-defined id in the hierarchy, findViewById(R.id.somename) will always return the XML-defined View so id'd.

Dynamically Creating Views and Assigning IDs

  • In layout XML, define an empty ViewGroup with id.
  • Such as a LinearLayout with android:id="@+id/placeholder".
  • Use code to populate the placeholder ViewGroup with Views.
  • If you need or want, assign any ids that are convenient to each view.
  • Query these child views using placeholder.findViewById(convenientInt);

  • API 17 introduced View.generateViewId() which allows you to generate a unique ID.

If you choose to keep references to your views around, be sure to instantiate them with getApplicationContext() and be sure to set each reference to null in onDestroy. Apparently leaking the Activity (hanging onto it after is is destroyed) is wasteful.. :)

Reserve an XML android:id for use in code

API 17 introduced View.generateViewId() which generates a unique ID. (Thanks to take-chances-make-changes for pointing this out.)*

If your ViewGroup cannot be defined via XML (or you don't want it to be) you can reserve the id via XML to ensure it remains unique:

Here, values/ids.xml defines a custom id:

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

Then once the ViewGroup or View has been created, you can attach the custom id

myViewGroup.setId(R.id.reservedNamedId);

Conflicting id example

For clarity by way of obfuscating example, lets examine what happens when there is an id conflict behind the scenes.

layout/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>

To simulate a conflict, lets say our latest build assigned R.id.placeholder(@+id/placeholder) an int value of 12..

Next, MyActivity.java defines some adds views programmatically (via code):

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);
}

So placeholder and one of our new TextViews both have an id of 12! But this isn't really a problem if we query placeholder's child views:

// 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);

*Not so bad

调妓 2024-12-27 11:49:48

您只需使用 View.setId(integer) 即可。在 XML 中,即使您设置的是字符串 id,它也会转换为整数。因此,您可以使用任何(正)整数作为以编程方式添加的视图

根据查看文档

<块引用>

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

所以你可以使用任何你喜欢的正整数,但在这种情况下
可以是一些具有相同 id 的视图。如果你想搜索一些
层次结构中的视图调用 setTag 与一些关键对象可能是
方便。

归功于这个答案

You can just use the View.setId(integer) for this. In the XML, even though you're setting a String id, this gets converted into an integer. Due to this, you can use any (positive) Integer for the Views you add programmatically.

According to View documentation

The identifier does not have to be unique in this view's hierarchy.
The identifier should be a positive number.

So you can use any positive integer you like, but in this case there
can be some views with equivalent id's. If you want to search for some
view in hierarchy calling to setTag with some key objects may be
handy.

Credits to this answer.

强辩 2024-12-27 11:49:48

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

Yes, you can call setId(value) in any view with any (positive) integer value that you like and then find it in the parent container using findViewById(value). Note that it is valid to call setId() with the same value for different sibling views, but findViewById() will return only the first one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文