Как я могу использовать дубликаты идентификаторов в разных макетах? - PullRequest
14 голосов
/ 01 июня 2011

У меня есть два разных макета для двух разных видов деятельности.В каждом из этих макетов есть кнопка с одинаковым идентификатором: "@ + id / btnOK".Когда я программно устанавливаю свойство для одной из этих кнопок, я получаю NullPointerException.Но когда я меняю один из идентификаторов, все в порядке.

Правда ли, что у нас не может быть повторяющихся идентификаторов в разных макетах в Android?

Ответы [ 5 ]

23 голосов
/ 27 июня 2011

По теме «Дублирующиеся идентификаторы в макетах», извлеченные из разработчиков Android

Определение идентификаторов для объектов просмотра важно при создании RelativeLayout. В относительной компоновке родственные виды могут определять свою компоновку относительно другой родственной точки, на которую ссылается уникальный идентификатор.

Идентификатор не обязательно должен быть уникальным для всего дерева, но он должен быть уникальным для той части дерева, которую вы ищете (которая часто может быть целым деревом, поэтому лучше всего быть полностью уникальным, когда это возможно).

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

2 голосов
/ 16 марта 2012

У вас могут быть одинаковые идентификаторы, но они должны быть в разных макетах.Один и тот же макет не может обрабатывать дубликаты идентификаторов.Я взял два макета, как вы сделали, содержащие кнопки, имеющие «btn».Я звоню в Activity2 с файлом newxml.xml из Activity1 с файлом main.xml.

Вот мой код:

main.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Next" />

</LinearLayout>

Activity1 :

setContentView(R.layout.main);

Button button=(Button) findViewById(R.id.btn);
button.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent intent=new Intent(Activity1.this,Activity2.class);
            startActivity(intent);
        }
    });

newxml :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button 
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Previous"/>

</LinearLayout>

Activity2 :

setContentView(R.layout.newxml);

Button button=(Button) findViewById(R.id.btn);
button.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
        finish();
    }
});
2 голосов
/ 01 июня 2011

Я полагаю, что в классе R.java возникнет проблема, так как этот класс будет иметь открытые статические члены, соответствующие каждому View идентификатору.

Чтобы он работал, класс R.javaнужно переименовать некоторые из этих идентификаторов, а потом как их найти?

0 голосов
/ 14 декабря 2018

Мне кажется правильным (а иногда и вполне естественным) использовать дубликаты идентификаторов, если вы делаете это правильно: вместо Activity.findViewById(), который всегда возвращает первое совпадающее представление, используйте ViewGroup.findViewById() (ViewGroup canbe LinearLayout, FrameLayout и т. д.), который возвращает представление в группе представлений.

Чтобы избежать предупреждений lint:

  1. (предпочтительно) Поместить содержимое группы просмотра вРазделяйте XML-формат и используйте

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

    Таким образом, вы можете иметь несколько включений одного и того же макета с разными родительскими идентификаторами (но с одинаковыми дочерними идентификаторами), и lint никогда не будет жаловаться.1018 * Отключить предупреждение Lint для проекта, сняв флажок « Дублировать идентификаторы в одном макете » в *Settings/Editor/Inspections*

0 голосов
/ 06 июня 2011

Я решил проблему, но не нашел причину. В моем файле манифеста одно из действий имело «android: label =" @ string / app_name ». Я удалил его и установил его для своего основного действия.

Предыдущий манифест:

<activity android:name=".ui.ActLogin">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity android:name=".ui.ActTest" android:label="@string/app_name">
</activity>

Новый манифест:

<activity android:label="@string/app_name" android:name=".ui.ActLogin">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity android:name=".ui.ActTest">
</activity>

Кто-нибудь знает причину?

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