简体   繁体   English

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

[英]How can I assign an ID to a view programmatically?

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? 在XML文件中,我们可以为像android:id="@+id/something"这样的视图分配ID,然后调用findViewById() ,但是在以编程方式创建视图时,如何分配ID?

I think setId() is not the same as default assignment. 我认为setId()与默认赋值不同。 setId() is extra. setId()是额外的。

Can anybody correct me? 任何人都可以纠正我吗?

Android id overview Android id概述

An Android id is an integer commonly used to identify views; Android id是一个通常用于标识视图的整数; this id can be assigned via XML (when possible) and via code (programmatically.) The id is most useful for getting references for XML-defined View s generated by an Inflater (such as by using setContentView .) 这个id可以通过XML(如果可能),并且经由代码分配(编程)的id是用于获取用于XML定义的引用最有用的View S按一个产生Inflater (例如,通过使用setContentView 。)

Assign id via XML 通过XML分配id

  • Add an attribute of android:id="@+id/ somename " to your view. 在您的视图中添加android:id="@+id/ somename "的属性。
  • When your application is built, the android:id will be assigned a unique int for use in code. 构建应用程序时,将为android:id分配一个唯一的 int ,以便在代码中使用。
  • Reference your android:id 's int value in code using " R.id. somename" (effectively a constant.) 使用“ R.id. somename”(实际上是常量)在代码中引用你的android:idint值。
  • this int can change from build to build so never copy an id from gen/ package.name/ R.java , just use " R.id. somename". 这个int可以从build更改为build,所以永远不要复制 gen/ package.name/ R.java 的id ,只需使用“ R.id. somename”。
  • (Also, an id assigned to a Preference in XML is not used when the Preference generates its View .) (另外,当Preference生成其View时,不会使用分配给XML中的Preferenceid 。)

Assign id via code (programmatically) 通过代码分配id (以编程方式)

  • Manually set id s using someView.setId( int ); 使用someView.setId( int );手动设置id );
  • The int must be positive, but is otherwise arbitrary- it can be whatever you want (keep reading if this is frightful.) int必须是正数,否则是任意的 - 它可以是你想要的任何东西(如果这是可怕的话,继续阅读。)
  • For example, if creating and numbering several views representing items, you could use their item number. 例如,如果创建和编号表示项目的多个视图,则可以使用其项目编号。

Uniqueness of id s id的唯一性

  • XML -assigned id s will be unique. XML -assigned id将是唯一的。
  • Code-assigned id s do not have to be unique 代码分配的id 都不具备的是唯一的
  • Code-assigned id s can (theoretically) conflict with XML -assigned id s. 代码分配的id可以(理论上)与XML -assigned id冲突。
  • These conflicting id s won't matter if queried correctly (keep reading) . 如果正确查询(继续阅读),这些冲突的id将无关紧要。

When (and why) conflicting id s don't matter 何时(和为什么)冲突的id无关紧要

  • 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 . findViewById(int)将从您指定的视图中以递归方式迭代遍历视图层次结构并返回其找到的具有匹配id的第一个View
  • As long as there are no code-assigned id s assigned before an XML-defined id in the hierarchy, findViewById(R.id.somename) will always return the XML-defined View so id 'd. 只要在层次结构中的XML定义的id之前没有分配代码分配的idfindViewById(R.id.somename)将始终返回XML定义的View,因此id d。

Dynamically Creating Views and Assigning ID s 动态创建视图和分配ID

  • In layout XML, define an empty ViewGroup with id . 在布局XML中,使用id定义一个空的ViewGroup
  • Such as a LinearLayout with android:id="@+id/placeholder" . 例如带有android:id="@+id/placeholder"LinearLayout
  • Use code to populate the placeholder ViewGroup with View s. 使用代码使用View s填充占位符ViewGroup
  • If you need or want, assign any id s that are convenient to each view. 如果您需要或想要,请为每个视图分配任何方便的id
  • Query these child views using placeholder.findViewById(convenientInt); 使用placeholder.findViewById(convenientInt)查询这些子视图;

  • API 17 introduced View.generateViewId() which allows you to generate a unique ID. API 17引入了View.generateViewId() ,允许您生成唯一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 . 如果您选择保留对视图的引用,请确保使用getApplicationContext()实例化它们,并确保在onDestroy中将每个引用设置为null。 Apparently leaking the Activity (hanging onto it after is is destroyed) is wasteful.. :) 显然泄漏 Activity (被破坏后挂在它上面)是浪费的.. :)

Reserve an XML android:id for use in code 保留XML android:id以在代码中使用

API 17 introduced View.generateViewId() which generates a unique ID. API 17引入了 View.generateViewId() ,它生成一个唯一的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: 如果无法通过XML定义ViewGroup (或者您不希望它),则可以通过XML保留id以确保它保持唯一:

Here, values/ids.xml defines a custom id : 这里, values / ids.xml定义了一个自定义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 然后,一旦创建了ViewGroup或View,您就可以附加自定义ID

myViewGroup.setId(R.id.reservedNamedId);

Conflicting id example 冲突的id示例

For clarity by way of obfuscating example, lets examine what happens when there is an id conflict behind the scenes. 为了清楚地通过混淆示例,让我们来看看在幕后发生id冲突时会发生什么。

layout/mylayout.xml 布局/ 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 .. 为了模拟冲突,我们说最新的构建指定了R.id.placeholder@+id/placeholder )的int值为 12 ..

Next, MyActivity.java defines some adds views programmatically (via code): 接下来, 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);
}

So placeholder and one of our new TextView s both have an id of 12! 因此placeholder和我们的一个新TextView都具有12的id 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 *没那么糟糕

You can just use the View.setId(integer) for this. 您可以使用View.setId(integer) In the XML, even though you're setting a String id, this gets converted into an integer. 在XML中,即使您正在设置String id,也会将其转换为整数。 Due to this, you can use any (positive) Integer for the Views you add programmatically. 因此,您可以对以编程方式添加的Views使用任何(正)整数。

According to View documentation 根据View文档

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. 所以你可以使用你喜欢的任何正整数,但在这种情况下,可能会有一些具有相同id的视图。 If you want to search for some view in hierarchy calling to setTag with some key objects may be handy. 如果你想在层次结构中搜索一些视图,调用setTag,一些关键对象可能会很方便。

Credits to this answer . 相信这个答案

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) . 是的,您可以在任何视图中使用您喜欢的任何(正)整数值调用setId(value) ,然后使用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. 请注意,为不同的兄弟视图调用具有相同值的setId()是有效的,但findViewById()将仅返回第一个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何为Android中以编程方式创建的数组分配ID? - How can I assign an id to a programmatically created array in android? 在Android中以编程方式分配视图ID - Assign a view ID programmatically in Android 我可以为我以编程方式构造的可绘制对象分配ID吗? - Can I assign a id to a drawable, which I construct programmatically? 如何以编程方式分配ID,例如“ android:id / tabcontent”? - How do I programmatically assign an id such as 'android:id/tabcontent''? Android如何才能以编程方式向自定义视图分配自定义参数? - Android how can I assign custom parameters programmatically to my inflated view? 如何以编程方式设置视图的LayoutParams? - How can I set the LayoutParams of an View Programmatically? 如何在RelativeyLayout中以编程方式将视图放置在另一个视图下? - How can I place a View under another View programmatically in RelativeyLayout? Android如何以编程方式获取图像按钮的ID? - Android how can i get the image button's id programmatically? 如何以编程方式为我的EditText字段定义ID? - How can I define an ID for my EditText field programmatically? 如何在ViewFlipper中为每个视图分配单独的类? - How can I assign a separate class for each view in a ViewFlipper?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM