이번에는 "Android Layout Tricks #1" ( Layout 최적화하기 ) 에 대해 알아보겠습니다.
이 글은 http://android-developers.blogspot.com/2009/02/android-layout-tricks-1.html 을 의역한 내용입니다.
Android Layout Tricks #1 ( Layout 최적화하기 )
Android UI toolkit 은 여러가지 layout manager 들을 제공합니다. 이것들은 사용하기가 쉽고, 대부분의 경우 당신은 약간의 기본 기능들만 사용하여 UI 를 구성하고 있습니다. 하지만 약간의 기본 기능들만 사용하는 것은 UI 를 구성하는 가장 효율적인 방법이 아닙니다. 가장 효율적이지 못한 경우는 LinearLayout 의 남발입니다. LinearLayout 의 남발은 view hierarchy 의 급증을 초래하게 됩니다. 어떤 view 던 application 에 더하는 것은 cost를 유발하는 것이며, 특히 layout manager 들을 붙이는 것은 더욱 더 큰 cost 를 유발합니다. 이 cost 는 초기화와 layouting, 그리고 drawing 을 더 느리게 하는 것을 말하죠. weight parameter 를 사용하여 LinearLayout 을 nesting 하는 경우에는 그 비용이 훨씬 커집니다. 두번이나 child 의 size 를 measure 하기 때문이죠.
다음의 아주 간단하지만 일반적인 layout 의 예를 보시겠습니다. list item 으로 왼쪽에는 icon 이 있고, 오른쪽 상단에는 title, 오른쪽 하단에는 description 이 있습니다. 다음과 같이 생긴 녀석이죠.
더 확실히 이해하기 위해 HierarchyViewer 를 통해 capture 된 이 한개의 ImageView 와 두개의 TextView의 layout 모양을 살펴보겠습니다.
이것을 LinearLayout 을 통해서 구현하는 것은 매우 직관적입니다. 전체는 horizontal LinearLayout 을 쓰면 되고, 오른쪽 TextView 들은 vertical LinearLayout 을 통해 배치하면 되겠습니다. 소스는 다음과 같겠죠.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="6dip">
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginRight="6dip"
android:src="@drawable/icon" />
<LinearLayout
android:orientation="vertical"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:gravity="center_vertical"
android:text="My Application" />
<TextView
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:singleLine="true"
android:ellipsize="marquee"
android:text="Simple application that shows how to use RelativeLayout" />
</LinearLayout>
</LinearLayout>
이 layout 은 잘 작동할겁니다. 하지만 ListView 의 item 으로 쓰기에는 낭비가 너무 심합니다. RelativeLayout 을 사용하여 같은 효과를 내면서도 한개의 View 를 절약할 수 있습니다. 이 한개 view 의 절약은 view hierarchy 에서 한 level을 절감할 수 있습니다. 개별 list item 마다 절약이 가능하니 얼마나 좋을지는 판단에 맡기겠습니다. RelativeLayout 으로 구현하면 다음과 같습니다.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="6dip">
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="6dip"
android:src="@drawable/icon" />
<TextView
android:id="@+id/secondLine"
android:layout_width="fill_parent"
android:layout_height="26dip"
android:layout_toRightOf="@id/icon"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:singleLine="true"
android:ellipsize="marquee"
android:text="Simple application that shows how to use RelativeLayout" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/icon"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_above="@id/secondLine"
android:layout_alignWithParentIfMissing="true"
android:gravity="center_vertical"
android:text="My Application" />
</RelativeLayout>
이 새로운 구현은 정확히 이전의 구현과 일치합니다, 한가지 경우를 제외하면 말이죠. list item 은 TextView 들을 2줄, title과 description, 로 표현하는데, description 쪽이 GONE 으로 visibility 가 setting 되었을 때의 결과가 조금 다릅니다.
RelativeLayout 에서 view 는 부모, RelativeLayout 자신, 그리고 다른 view 를 기준으로 정렬됩니다. 예를 들어 우리는 RelativeLayout 자신의 bottom 에 description 을 정렬했고, title 은 description 위면서, 부모의 top 기준으로 정렬이 되어 있죠. description 이 GONE 으로 mark 되면, RelativeLayout 은 title 의 bottom 을 어디에 맞춰야 할지 모릅니다. 이를 해결하기 위해서 우리는 alignWithParentIfMissing 이라는 속성을 사용합니다.
이 boolean parameter 는 RelativeLayout 에게 해당 제약사항을 주는 target 이 없을 경우 부모에 align 시키라는 의미입니다. 예를 들어 GONE 으로 표시된 녀석의 오른쪽에 view 를 배치시키도록 하면서 alignParentIfMissing 을 true 값으로 주면, RelativeLayout 은 view 를 left edge 에 위치시킵니다. 우리 예제의 경우는 alignWithParentIfMissing 을 사용할 경우 title 의 bottom 을 RelativeLayout 의 bottom 에 위치시키는 것이지요. 결과는 다음과 같습니다.
이제 2개의 layouting 결과는 같아졌습니다, description 이 GONE 이 되어도 말이죠. 하지만 hierarchy 는 LinearLayout 을 하나 생략하여 더 간단해 졌으며, weight 을 사용하지 않게 되어 더 효율적이 되었습니다. 다음의 HierarchyViewer 를 통해 생성된 view hierarchy 결과를 확인하면 차이가 더 명확하겠죠.
다시 강조하지만, ListVIew 의 item 같은 layout 을 사용할 때 이런 차이는 더 극명하게 나타납니다. 이 예제가 어떻게 UI 를 최적화하는데 도움이 되었길 바랍니다.
댓글