Как программно назначить идентификатор для представления?
В 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
"sint
значение в коде, используя "R.id.
somename"(фактически постоянная.) - этот
int
может меняться от сборки к сборке, поэтому никогда не копируйте идентификатор изgen/
имя пакета/R.java
просто используйR.id.
SomeName". - (Также
id
назначен наPreference
в XML не используется, когдаPreference
генерирует егоView
.)
приписывать id
через код (программно)
- Ручная настройка
id
с помощьюsomeView.setId(
ИНТ);
-
int
должен быть положительным, но в противном случае он может быть произвольным - это может быть все, что вы хотите (продолжайте читать, если это страшно.) - Например, если вы создаете и нумеруете несколько представлений, представляющих элементы, вы можете использовать их номер элемента.
Уникальность id
s
XML
-assignedid
с будет уникальным.- Код, назначенный
id
не должны быть уникальными - Код, назначенный
id
может (теоретически) конфликтовать сXML
-assignedid
s. - Эти противоречивые
id
s не имеет значения, если запрос правильно (продолжайте читать).
Когда (и почему) конфликтуют id
не имеет значения
findViewById(int)
будет рекурсивно выполнять итерацию в глубину по иерархии представления из указанного вами представления и возвращать первоеView
находит с соответствиемid
,- Пока нет назначенного кода
id
присваивается перед определенным XMLid
в иерархии,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()
вернет только первый.