티스토리 뷰
이번 시간에는 복잡한 xml을 좀 더 보기좋고 효율적으로 바꿀수 있는 xml tag(include, merge)에 대해 알아보겠습니다.
<include> tag 사용
먼저 <include> 태그를 사용하면 레이아웃을 여러 파일로 나눌 수 있습니다. 복잡하거나 아주 긴 GUI를 구현하는데 도움이 됩니다.
reuse_item1.xml, reuse_item2.xml 파일을 사용하여 복잡한 레이아웃을 구성한다고 가정하고, 해당 activity의 xml(이름은 main_activity로 하였습니다.)을 작성해 봤습니다.
main_activity.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- First include file -->
<include layout="@layout/reuse_item1" />
<!-- Second include file -->
<include layout="@layout/reuse_item2" />
</LinearLayout>
이제 activity의 xml을 작성했으니 reuse_item1.xml 및 reuse_item2.xml 도 작성해보겠습니다.
reuse_item1.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/textView1"
android:text="First include"
android:textAppearance="?android:attr/textAppearanceMedium"/>
reuse_item2.xml
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/button1"
android:text="Button" />
각 xml들은 위와 같이 뷰그룹 없이 위젯으로만 작성하였습니다.
참고로 xmlns:android="http://schemas.android.com/apk/res/android 안드로이드 네임 스페이스를 선언해야합니다.
그럼 main_activity.xml 의 최종 렌더링 된 모습을 살펴 보겠습니다.
main_activity.xml 렌더링된 모습
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- First include file -->
<TextView
android:id="@+id/textView1"
android:text="First include"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<!-- Second include file -->
<Button
android:id="@+id/button1"
android:text="Button" />
</LinearLayout>
이렇게 <include>를 통해 구현한 xml은 여러분이 구현한 자바 코드에서 findViewById(R.id.textView1)를 통해 해당 위젯을 잘 받아올 수 있습니다.
이제 좀 더 복잡한 xml에 대해서도 같은 작업을 진행해 보겠습니다. 기존에는 reuse 된 xml들이 TextView 하나만 가지고 있었는데 이제 두 개 이상의 위젯을 넣어보도록 하겠습니다. 우선 해당 xml에 존재하는 위젯들을 ViewGroup으로 감싸줘야 합니다. 위젯이 두개 이상이라 꼭 감싸줘야됩니다.
저는 LinearLayout으로 감싸보겠습니다.
아래와 같이 reuse_item1.xml을 수정하였습니다.
reuse_item1.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/reuse_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:text="Second include"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<TextView
android:id="@+id/textView2"
android:text="More text"
android:textAppearance="?android:attr/textAppearanceMedium"/>
</LinearLayout>
reuse_item2.xml, main_activity.xml은 그대로 사용한다는 가정하에 바꿘 reuse_item1.xml로 인해 main_activity.xml은 다음과 같이 렌더링됩니다.
reuse_item1.xml 수정 이후 main_activity.xml의 렌더링 된 모습
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- First include file -->
<LinearLayout
android:id="@+id/reuse_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:text="Second include"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<TextView
android:id="@+id/textView2"
android:text="More text"
android:textAppearance="?android:attr/textAppearanceMedium"/>
</LinearLayout>
<!-- Second include file -->
<Button
android:id="@+id/button1"
android:text="Button" />
</LinearLayout>
<!-- First include file --> 주석 밑으로 변경한 reuse_item1.xml의 요소들이 잘 들어갔습니다.
이렇게 손쉽게 <include> 를 사용하여 복잡한(?) 레이아웃을 보기 쉽게 나눠보았습니다.
그런데 위 main_activity.xml은 한가지 문제점을 가지고 있습니다.
바로 <include>로 인해 불필요하게 LinearLayout의 중복이 발생하였습니다.
Layout을 분리해서 좀 더 깔끔하게 구현해 보려고 한건데, 이로 인해 부작용이 발생하였습니다.
이 문제를 어떻게 해야될까요? reuse_item1.xml은 include 하지 말고 main_activity.xml 파일에 직접 채워 넣을까요?
아닙니다. 눈치 채셨겠지만 저희는 <merge> tag를 이용하여 이 문제를 좀 더 스마트하게 해결할 수 있습니다.
<merge> tag 사용
<merge> 는 이러한 종류의 중복 문제를 처리하는 최상위 요소를 제공하는 더미 태그입니다.
우리는 문제의 그 reuse_item1.xml을 다음과 같이 고칠 수 있습니다.
<merge>를 적용한 include1.xml
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="@+id/textView1"
android:text="Second include"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<TextView
android:id="@+id/textView2"
android:text="More text"
android:textAppearance="?android:attr/textAppearanceMedium"/>
</merge>
그럼 이제 main_activity.xml 이 어떻게 렌더링 되나 살펴보겠습니다.
새롭게 렌더링 된 main_activity.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- First include file -->
<TextView
android:id="@+id/textView1"
android:text="Second include"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<TextView
android:id="@+id/textView2"
android:text="More text"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<!-- Second include file -->
<Button
android:id="@+id/button1"
android:text="Button" />
</LinearLayout>
<merge> 를 통해 우리가 고민하던 문제가 사라졌습니다.
그런데!!!
우리는 <include>의 문제를 수정하면서 <merge>의 새로운 문제에 당면할 수 있습니다.
사실 위와 같은 구조의 xml에서는 <merge>로 인해 다른 문제가 발생하지 않습니다.
main_activity.xml을 조금 수정해서 <merge>의 단점을 들춰보겠습니다.
<merge>의 단점을 확인할 수 있는 main_activity.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- First include file -->
<include
android:id="@+id/reuse_layout1"
layout="@layout/reuse_item1" />
<!-- Second include file -->
<include
android:id="@+id/reuse_layout2"
layout="@layout/reuse_item1" />
</LinearLayout>
수정한 main_activity.xml에서는 동일한 reuse_item1.xml을 두 번 include 하였고, 각 include에 id를 지정하였습니다.
이전 예제에서는 id를 지정하지 않았지만, 우리는 <include> 를 사용할 때 id를 지정할 수 있습니다. <include> 에 설정된 id나 다른 attribute들은 include된 layout의 최상단 layout에 설정되게 됩니다. 그래서 이 id를 통해 나중에 findViewById()를 통해 원하는 위젯이나 ViewGroup을 가져올 때 사용할 수 있는 것이죠.
하지만 <merge>를 reuse_item1.xml에서 사용하면서 include 될 reuse_tiem1.xml의 root layout이 사라지게 되었습니다. 따라서 <include> 에서 지정한 id는 모두 사라지게 됩니다.
id가 사라졌기 때문에 우리는 reuse_item1.xml의 내부 위젯에 접근할 방법이 사라졌습니다. <merge> 의 단점이라고 할만하죠?
따라서 <merge>를 쓴 xml은 한 곳에서 두 번 <include>하지 않아야합니다.
이렇게 <include>, <merge> 에 대해 알아봤습니다. 혹시 잘못된 점이나 궁금한 점 있으면 댓글로 남겨주세요.
감사합니다.
'개발 > 안드로이드' 카테고리의 다른 글
[안드로이드 / android] 알파값 비율을 헥사값으로 변환하기 Alpha percentages to hex (0) | 2018.07.05 |
---|---|
[안드로이드 / android] 안드로이드 작명법 Naming Conventions (0) | 2018.07.05 |
[안드로이드 / android] "please select android sdk" 오류 수정 (0) | 2018.07.01 |
[안드로이드 / android] 해상도에 대한 이해 (1) | 2018.06.28 |
[안드로이드 / android] 로그 필요할 때만 활성화하기 (0) | 2018.06.28 |