Как программно назначить идентификатор для представления?

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

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

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

3 ответа

Решение

Android id обзор

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

приписывать id с помощью XML

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

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

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

Уникальность id s

  • XML -assigned id с будет уникальным.
  • Код, назначенный id не должны быть уникальными
  • Код, назначенный id может (теоретически) конфликтовать с XML -assigned id s.
  • Эти противоречивые id s не имеет значения, если запрос правильно (продолжайте читать).

Когда (и почему) конфликтуют id не имеет значения

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

Динамическое создание видов и назначение ID s

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

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

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

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

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

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

Здесь values ​​/ ids.xml определяет пользовательский id :

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

Затем, когда ViewGroup или View были созданы, вы можете прикрепить пользовательский идентификатор

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

Так placeholder и один из наших новых TextView у обоих есть 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, даже если вы устанавливаете идентификатор String, он преобразуется в целое число. Благодаря этому вы можете использовать любое (положительное) целое число для Views вы добавляете программно.

В соответствии с View документация

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

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

Кредиты на этот ответ.

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

Другие вопросы по тегам