Как назначить ID представлению программным способом?

в XML-файл, мы можем присвоить ID к android:id="@+id/something" и затем вызов findViewById(), но при создании представления программно, как я могу присвоить ID?

Я думаю setId() не совпадает по умолчанию. setId() дополнительно.

может кто-нибудь меня поправит?

3 ответов


Android id обзор

Андроид id - это целое число, обычно используемое для идентификации представлений; это id может быть назначен через XML (когда это возможно) и через код (программно.) The id наиболее полезно для получения ссылок для XML-определенных Views генерируется Inflater (например, с помощью setContentView.)

присвоить id via XML

  • добавить атрибут android:id="@+id/содержаться" в свой вид.
  • когда ваше приложение построено,android:id назначается уникальный int для использования в коде.
  • ссылка android:id ' s int значение в коде с помощью"R.id.somename "(фактически константа.)
  • этой int может меняться от сборки к сборке так никогда не копировать id от gen/ пакет.имя/R.java, Просто используйте "R.id.somename".
  • (также, an id назначенные к Preference в XML не используется, когда Preference порождает View.)

присвоить id через код (программно)

  • установить вручную idС помощью someView.setId(int);
  • на int должно быть положительным, но в остальном произвольным - это может быть все, что вы хотите (продолжайте читать, если это страшно.)
  • например, при создании и нумерации нескольких представлений, представляющих элементы, можно использовать их элемент число.

уникальность ids

  • XMLназначен ids будет уникальным.
  • код, присвоенный ids do не должны быть уникальными
  • код, присвоенный ids может (теоретически) конфликтовать с XMLназначен ids.
  • эти противоречивые ids не будет иметь значения, если запрос правильно (продолжайте читать).

когда (и почему) противоречие ids не имеет значения

  • findViewById(int) будет повторять глубину сначала рекурсивно через иерархию представлений с целью указать и вернуть первый View он находит с соответствующим id.
  • пока нет назначенного кода ids назначается перед XML-определенным id в иерархии, findViewById(R.id.somename) всегда будет возвращать XML-определенное представление so id ' d.

динамическое создание представлений и Назначение IDs

  • в макете XML определите пустой ViewGroup с id.
  • например,LinearLayout с android:id="@+id/placeholder".
  • используйте код для заполнения заполнителя ViewGroup с Views.
  • Если вам нужно или хотите, назначьте любой ids, которые удобны для каждого вида.
  • запрос этих дочерних представлений с помощью заполнителя.findViewById (convenientInt);

  • API 17 представил View.generateViewId() что позволяет генерировать уникальный идентификатор.

если вы решите сохранить ссылки на свои взгляды вокруг, обязательно создайте их с помощью getApplicationContext() и обязательно установите для каждой ссылки значение null в onDestroy. Видимо утечка the Activity (висеть на нем после того, как он уничтожен) расточительно.. :)

зарезервировать XML android:id для использования в коде

API 17 введен View.generateViewId() , который генерирует уникальный идентификатор. (спасибо take-chances-make-changes за указание на это.)*

если ViewGroup не может быть определен через XML (или вы не хотите, чтобы это было) вы можете зарезервировать идентификатор через XML, чтобы убедиться, что он остается уникальным:

здесь значения/идентификаторы.в 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) an 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);
}

так placeholder и один из наших новых 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);

*не так уж и плохо


вы можете просто использовать View.setId(integer) для этого. В XML, даже если вы устанавливаете идентификатор строки, это преобразуется в целое число. Благодаря этому, вы можете использовать любое (положительное) целое число к Views добавить программно.

По данным View документация

идентификатор не должен быть уникальным в иерархии этого вида. Идентификатор должен быть положительным числом.

Так что вы можете использовать любой положительное целое число, но в этом случае есть могут быть некоторые представления с эквивалентными идентификаторами. Если вы хотите, чтобы искать некоторые представление в иерархии вызов setTag с некоторыми ключевыми объектами может быть удобный.

кредиты ответ.


Да, вы можете позвонить setId(value) в любом представлении с любым (положительным) целочисленным значением, которое вам нравится, а затем найти его в Родительском контейнере, используя findViewById(value). Обратите внимание, что действительно вызвать setId() С одинаковым значением для разных представлений брата, но findViewById() возвращает только первый.