Android XML 레이아웃의 '포함'태그가 실제로 작동합니까?


84

Android 레이아웃 파일에서 <include>를 사용할 때 속성을 재정의 할 수 없습니다. 버그를 검색했을 때 Declined Issue 2863을 찾았습니다 .

"태그 포함이 손상되었습니다 (레이아웃 매개 변수 재정의가 작동하지 않음)."

Romain은 이것이 테스트 스위트와 그의 예제에서 작동한다는 것을 나타 내기 때문에 뭔가 잘못하고있는 것 같습니다.

내 프로젝트는 다음과 같이 구성됩니다.

res/layout
  buttons.xml

res/layout-land
  receipt.xml

res/layout-port
  receipt.xml

buttons.xml에는 다음과 같은 내용이 포함됩니다.

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

  <Button .../>

  <Button .../>
</LinearLayout>

그리고 세로 및 가로 영수증 .xml 파일은 다음과 같습니다.

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

  ...

  <!-- Overridden attributes never work. Nor do attributes like
       the red background, which is specified here. -->
  <include
      android:id="@+id/buttons_override"
      android:background="#ff0000"
      android:layout_width="fill_parent"
      layout="@layout/buttons"/>

</LinearLayout>

내가 무엇을 놓치고 있습니까?


이 질문은 지원되지 않는 방식으로 포함을 사용하려고 할 때 Android 개발자 도구에서 참조합니다.
ThomasW

답변:


132

방금 문제를 찾았습니다. 첫째, layout_ * 속성 만 재정의 할 수 있으므로 배경이 작동하지 않습니다. 그것은 문서화 된 행동이며 단순히 나의 감독 일뿐입니다.

실제 문제는 LayoutInflater.java에서 찾을 수 있습니다.

// We try to load the layout params set in the <include /> tag. If
// they don't exist, we will rely on the layout params set in the
// included XML file.
// During a layoutparams generation, a runtime exception is thrown
// if either layout_width or layout_height is missing. We catch
// this exception and set localParams accordingly: true means we
// successfully loaded layout params from the <include /> tag,
// false means we need to rely on the included layout params.
ViewGroup.LayoutParams params = null;
try {
   params = group.generateLayoutParams(attrs);
} catch (RuntimeException e) {
   params = group.generateLayoutParams(childAttrs);
} finally {
   if (params != null) {
     view.setLayoutParams(params);
   }
}

<include> 태그에 layout_width와 layout_height가 모두 포함되어 있지 않으면 RuntimeException이 발생하고 로그 문도없이 자동으로 처리됩니다.

해결책은 layout_ * 속성을 재정의하려는 경우 <include> 태그를 사용할 때 항상 layout_width와 layout_height를 모두 포함하는 것입니다.

내 예는 다음과 같이 변경되어야합니다.

<include
      android:id="@+id/buttons_override"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      layout="@layout/buttons"/>

33
이건 말도 안돼. 나는 이것을 작동시킬 수 없었고, 심지어 높이와 너비라고 가정 한 치수를 재정의하려고 할 때 높이와 너비가 모두 필요하다는 문서 언급도 보았습니다. 그러나 내가 재정의하려는 것은 여백 뿐이며 실제로는 차원이 아닙니다. 왜 내가 변경하고 싶은 것이 layout_marginRight 일 때 둘 다 또는 둘 중 하나를 지정해야하는 이유는 무엇입니까? Grrr, Android, 때로 너무 실망 스럽습니다.
Artem Russakovskii 2010

1
참고로 안드로이드 린트가 당신에게 오류를 줄 것이다 (layout_width도에 지정하지 않으면 레이아웃 매개 변수는 무시 layout_height <포함> 태그)은 높이와 너비 속성을 모두 무시하지 않는 경우
바이너리

10

포함 된 모든 속성을 재정의 할 수 있도록 개선 요청 을 제출했습니다 .

TextView필드 값이 아닌 두 개의 동일한 레이아웃이 있다고 가정 합니다. 현재 저는 런타임에 레이아웃을 수정하거나 XML을 복제했습니다.

예를 들어 "hello"및 "world"값이있는 두 개의 매개 변수를 layout1에 전달하려면 다음을 수행하십시오.

<include layout="@layout/layout1a" params="textView=hello|editText=world" />

layout1a.xml :

<merge><TextView text="@param/textView"><EditText hint="@param/editText"></merge>

대체 구현은 캡슐화를 중단하고 include 문이 다음과 같은 값을 재정의하도록 허용합니다.

<include layout="@layout/layout1b" overrides="@id/textView.text=hello|@id/editText.hint=world" />

layout1b.xml :

<merge><TextView id="@+id/textView"><EditText hint="@+id/editText"></merge>


1
고려 새로운 데이터 바인딩 물건을 복용은 <include>더 자주 지금, ATTR 최우선 정말이 있어야 기능이 사용됩니다
드미트리 Gryazin

1

Eclipse에서 GUI 빌더를 사용할 때 android : id 태그를 포함하지 않는 경우가 있습니다. 빌더에서 TextView에 추가했는지 (알았을 때) ListView 레이아웃에서 사용중인 ID를 확인하십시오.

<TextView android:text="@+id/textView1"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" />
...

된다

<TextView android:id="@+id/textView1"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" />
...

'거짓' '거짓'을 얻는 대신 :)를 얻고 정상적으로 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.