Как указать идентификатор при использовании включить в макет файла XML - PullRequest
104 голосов
/ 19 ноября 2009

В свой файл макета XML я включил другой файл XML макета (каждый с другим идентификатором Android).

<include layout="@layout/view_contact_name" android:id="+id/test1"/>
<include layout="@layout/view_contact_name" android:id="+id/test2"/>

Но когда я запускаю его в эмуляторе и запускаю средство просмотра иерархии, макет по-прежнему показывает «NO_ID», и в моем коде у меня есть findViewById(R.id.test1) и findViewById(R.id.test2) оба возвращают ноль.

Может кто-нибудь помочь мне с моей проблемой?

Ответы [ 9 ]

270 голосов
/ 22 сентября 2010

Укажите идентификатор в <include>

<include layout="@layout/test" android:id="@+id/test1" />

Затем используйте два findViewById для доступа к полям в макете

View test1View = findViewById(R.id.test1);
TextView test1TextView = (TextView) test1View.findViewById(R.id.text);

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

56 голосов
/ 13 января 2014

Я обнаружил, что если вы используете тег <merge> в вашем макете включения, то идентификатор включаемого перевода в тег объединения, который не является реальным представлением.

Так что либо удалите слияние, либо замените его каким-нибудь макетом.

Тор Норби написал :

Тег <include> не является реальным представлением, поэтому findByView не найдет его. Атрибут @id (и любые другие атрибуты, которые вы установили в теге include) вместо этого применяется к корневому тегу включенного макета. Таким образом, ваш activity.getView (R.id.included1) на самом деле должен быть <TextView>.

32 голосов
/ 19 ноября 2009

Romain Guy указывает , что вы можете переопределить идентификатор включенного макета, поместив атрибут android:id внутри тега <include>.

<include android:id="@+id/cell1" layout="@layout/workspace_screen" />
9 голосов
/ 14 марта 2017

Я думаю, что в верхнем ответе пропущен самый важный момент, и он может ввести людей в заблуждение, полагая, что тег <include/> создает представление, которое содержит включаемое содержимое.

Ключевым моментом является то, что id включает в себя , переданное в корневое представление файла макета включения.

То есть это:

// activity_main.xml
<include layout="@layout/somelayout" android:id="@+id/someid"/>

// somelayout.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />

Получается так:

// activity_main.xml
<ImageView
    android:id="@+id/someid"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />
4 голосов
/ 08 февраля 2012

Да похоже на это, но будьте осторожны, когда макет, вставленный в поле включения, является пользовательским, и вы хотите получить доступ к этому корневому макету. Этот макет в данном случае @ layout / test test фактически возвращается в первой строке.

test test1View = (test)findViewById(R.id.test1);
2 голосов
/ 12 августа 2016

Проблема в том, что мы пытаемся использовать идентификатор, который не объявлен в текущем файле макета. Вместо того, чтобы объявлять снова, можно просто сослаться на id, используя @+id/. Если вы реорганизуете оригинальное имя идентификатора через Android Studio, он также выполняет рефакторинг во включенном макете.

<include layout="@layout/toolbar"/>

<TextView
    android:id="@+id/txt_description"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    **android:layout_below="@+id/toolbar"**
    android:layout_marginTop="16dp"
    android:paddingLeft="8dp"
    android:paddingRight="8dp"/>
1 голос
/ 17 июля 2017

В случае использования <RecyclerView> найдите идентификатор <include>, используя экземпляр завышенного представления, иначе он вернет null .

public class ViewHolder extends RecyclerView.ViewHolder {

        private mTextView;

        public ViewHolder(View view) {
            super(view);
            View include_1 = view.findViewById(R.id.include_1);
            mTextView = (TextView) include_1.findViewById(R.id.text_id);
        }
    }
1 голос
/ 13 октября 2015
  1. Вы должны установить идентификатор каждого включаемого тега
  2. включенный дочерний элемент set a новый идентификатор если вы посмотрите, как создать новый идентификатор, посмотрите на эту запись: https://stackoverflow.com/a/15442898/1136117
0 голосов
/ 23 ноября 2016

Когда речь идет о включении, у вас либо есть идентификатор в корневом представлении внутри включенного файла макета, либо в самой строке включения, а не в обоих. Например:

<include layout="@layout/layout1" android:id="@+id/layout1"/>

Файл макета 1

<RelativeLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/layout2">

</RelativeLayout>

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...