2013-06-03 2 views
1

В соответствии с документацией, если я установил идентификатор тега <include> в файле ресурсов XML, он должен переопределить идентификатор корневого представления включенного макета. Однако, похоже, это не работает.Переопределение атрибута android: id с <include> не работает

Я создал очень простой проект для демонстрации его:

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <include 
     android:id="@+id/test" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     layout="@layout/merge_layout" /> 

</RelativeLayout> 

merge_layout.xml

<merge xmlns:android="http://schemas.android.com/apk/res/android"> 
    <LinearLayout 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"> 
     <Button 
      android:id="@+id/button" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" /> 
    </LinearLayout> 
</merge> 

Теперь, если я бегу это:

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    if (findViewById(R.id.button) == null) 
     throw new RuntimeException("button is null"); // Never happens 
    if (findViewById(R.id.test) == null) 
     throw new RuntimeException("test is null"); 
} 

затем он бросает второе исключение каждый раз. Я что-то упускаю?

ответ

3

Вам удалось обойти проблему, потому что ваш включенный макет оказался типом ViewGroup, который может быть корневым элементом xml. Если бы это было не так - т. Е. У вас был только TextView, вам нужно было использовать метку слияния, и, к сожалению, проблема возникла бы. Факт, включают в себя не может переопределить идентификатор раскладкой XML, который имеет сливаться как корень, как видно из источников LayoutInflater ниже ... Это делает слияния тег менее полезный :(

if (TAG_MERGE.equals(childName)) { 
// Inflate all children. 
rInflate(childParser, parent, childAttrs, false); 
} else { 
//... 
// We try to load the layout params set in the <include /> tag. 
//... 
// Inflate all children. 
rInflate(childParser, view, childAttrs, true); 

// Attempt to override the included layout's android:id with the 
// one set on the <include /> tag itself. 
// While we're at it, let's try to override android:visibility. 
+0

Почему это не поддерживается? Будет ли это слишком сложно или даже невозможно реализовать это в LayoutInflater? Может быть, кто-то может опубликовать патч здесь: https://source.android.com/source/submit-patches.html. Я не совсем понимаю, как LayoutInflater раздувает представления рекурсивно и не успеваешь это узнать, но если кто-то может это здорово ... –

0

Хорошо ответ был довольно очевиден, я неправильно понял, как работает <merge>. Я думал, что этот тег является обязательным, но это не так. В результате android:id был применен к тегу <merge> вместо <LinearLayout>.

Снятие тега <merge> решает проблему.

Смежные вопросы