'ui'에 해당되는 글 2건

  1. 재사용 가능한 UI 컴포넌트로 레이아웃 구성하기 (8)
  2. 윈도우 백그라운드 & UI 속도 (4)
재사용 가능한 UI 컴포넌트로 레이아웃 구성하기

안드로이드 플랫폼은 아주 다양한 UI 위젯을 제공합니다. 작은 위젯 조각을 합쳐서 복잡하고 정교한 인터페이스를 사용자에게 보여줄 수 있습니다.
하지만 애플리케이션을 개발 할 때 더 수준높은 인터페이스가 필요 할 때가 있습니다. 이 인터페이스를 완성하면서 그것도 효율적으로 만들기 위해서는 수 개의 표준위젯을 하나이면서 
재사용이 가능한 컴포넌트로 합쳐야 합니다.

예를 들어 프로그레스바와 취소버튼이 있고 아이콘과 제목, 설명이 있고 Positive 와 Negative 액션과 등등이 포함된 패널을 만듭니다.
이런 UI 컴포넌트를 만들기 위해서는 커스텀 뷰를 만드는 방법도 있지만 XML을 통해서 더욱 쉽게 할 수 있습니다.

안드로이드의 XML 레이아웃 파일에서 각각의 태그는 클래스 인스턴스에 맵핑(상호 연결)되어 있습니다.
클래스는 항상 뷰의 서브클래스이고 UI 툴은 뷰의 인스턴스에 맵핑되어있지 않은 세가지 태그를 지원합니다. <requestFocus />, <merge >, <include /> 입니다.
이 기술문서는 <include /> 태그를 어떻게 사용해서 순수하게 XML 로만 작성한 컴포넌트를 만드는지 알아보겠습니다.
<include /> 문과 같이써서 강력한 효과를 내는 <merge /> 태그의 사용법은 Merging Layouts 문서를 참고하세요.

<include /> 의 하는 일은 이름 그대로입니다.
즉, 다른 XML 레이아웃을 포함(include)하는 것입니다. 이 태그를 사용하는 것은 아래의 예제에서 보이는 것과 같이 아주 직관적입니다.
아래 예제는 안드로이드 내장 애플리케이션인 the source code of the Home application 에서 직접 가져왔습니다.

<com.android.launcher.Workspace
    android:id="@+id/workspace"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"

    launcher:defaultScreen="1">
</com.android.launcher.Workspace>


<include /> 태그안에서는 layout 속성만 써야합니다. 이 속성은 android 접두어가 붙지 않으면 포함 시키고자 하는 레이아웃 파일을 참조합니다. (사용한다는 말)
이 예제에서는 똑같은 레이아웃이 3번 연속으로 적용되었습니다. 이 태그는 또한 포함시키고자 하는 레이아웃의 몇가지 속성들을 오버라이드 할 수도 있습니다.
위의 예제에서는 android:id 를 사용해서 포함된 레이아웃의 루트 뷰(최상단 뷰)에 id를 부여 할 수 있습니다. id가 부여 되면 포함된 레이아웃의 id 도 오버라이드 됩니다.
또한 모든 레이아웃의 속성값들을 오버라이드 하는것도 가능합니다. 즉, 어떠한 android:layout_* 속성이라도 <include /> 태그안에서 쓰일 수 있다는 말입니다.
아래 예제에서는 똑같은 레이아웃이 두번 포함되었는데 첫번째 것만 레이아웃 속성들을 오버라이드 했습니다.
살펴보죠.

<!-- override the layout height and width -->
<include layout="@layout/image_holder"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent" />
<!-- do not override layout dimensions; inherit them from image_holder -->
<include layout="@layout/image_holder" />


주의
안드로이드 위젯의 dimension(폭과 높이)를 오버리아드 하고자 한다면 android:layout_height와 android:layout_width 속성을 다 오버라이드해야 합니다.
어느 한 가지 속성만 오버라이드 해서는 안됩니다. 한 가지만 오버라이드 하게 되면 아무 효과도 나타나지 않습니다. (weight 같은 이외의 속성들은 소스레이아웃에서 상속됩니다.)


<include />태그는 기기의 설정에따라 UI의 일부 특정한 부분만 수정하고자 할 때 매우 유용합니다.
예를 들어 액티비티의 메인 레이아웃 layout/ 폴더에 넣고 다른 레이아웃은(화면 방향을 예로 들어) layout_land/ 나 layout_port/ 폴더에 따로 보관 할 수 있습니다.
이렇게 레이아웃을 따로 보관한다면 유지보수가 한 층 더 용이해지는 것은 당연하겠죠.
저작자 표시 비영리 동일 조건 변경 허락
신고
윈도우 백그라운드 & UI 속도

안드로이드의 어떤 애플리케이션은 UI 의 속도를 최대한 끌어올릴 필요가 있습니다. 방법은 여러가지가 있습니다.
이번 문서에서는 애플리케이션의 그리기 성능과 액티비티의 지각(느낄 수 있는) 할 수 있는 스타트업 속도를 어떻게 향상시킬수 있는지 알아봅니다.
이 두가지 성능향상을 위한 기법은 한 요소에 의해 결정됩니다. 윈도우의 백그라운드 Drawable 입니다.

윈도우 백그라운드라는 용어는 약간은 오해의 소지가 있습니다. 하지만 액티비티에서 setContentView() 메서드를 이용해서 UI를 구축한다면
안드로이드는 액티비티의 윈도우에 뷰를 추가합니다. 하지만 윈도우는 단지 뷰만 추가하는 것이 아니라 몇몇 다른 요소들을 포함합니다.
가장 중요한 요소는 T-Mobile G1에서 사용되고 있는 DecorView 입니다.
아래 표에서 뷰 계층(View Hierarchy) 에서 확인해보죠.



DecorView는 윈도우의 Drawable을 실제로 담고 있는 뷰입니다.
액티비티에서 getWindow().setBackgroundDrawable() 메서드를 호출하고 DecorView의 백그라운드 Drawable을 바꾸면 윈도우의 백그라운드가 바뀝니다.
이 설정은 매우 구체적인 설정이고 차후버전이나 심지어 다른 기기들에서도 바꿀 수 있습니다.

개발시에 표준 안드로이드 테마를 사용한다면 안드로이드는 기본 백그라운드 Drawable을 액티비티의 기본 배경으로 사용합니다.
T-Mobile G1 에서 현재 사용하고 있는 표준 테마는 ColorDrawable 입니다. 대부분의 애플리케이션에서 백그라운드 Drawable은 잘 동작하며 혼자서도 동작이 가능합니다.
하지만 이 백그라운드 Drawable은 애플리케이션의 그리기 성능에 영향을 미칠 수 있습니다.
애플리케이션이 백그라운드에 항상 투명 사진을 그리는 예제를 한 번 보죠.





위의 스크린샷에서 윈도우의 백그라운드가 보이지 않는 것을 확인 할 수 있습니다.
윈도우의 백그라운드 전체가 ImageView 에 가려져 있죠. 애플리케이션이 44FPS(초당 프레임수)의 속도로 이미지를 그리고 있습니다.
이 애플리케이션이 더 빠르게 이미지를 그리게 하는 방법은 백그라운드 Drawable 을 제거하는 것입니다.
UI가 완전히 투명이기 때문에 백그라운드에 이미지를 그리는 것은 너무나 소모적이죠.
백그라운드 이미지를 제거하는 것은 성능을 끌어 올리는데 아주 좋습니다.





위의 스크린샷에서 백그라운드 이미지를 제거한 후에 FPS를 재어보니 51FPS가 나왔습니다. 초당 3밀리초의 차이는 T-Mobile G1의 메모리 버스에서 생기는 지연효과로 
풀스크린 이미지의 픽셀을 메모리 버스로 옮기는데 걸리는 시간을 의미합니다. 기본 백그라운드가 훨씬 더 화려하고 메모리 상주크기가 높다면 이 차이는 더 확연해 집니다.

윈도우의 백그라운드를 쉽게 삭제하는 방법은 커스텀 테마를 사용하는 것입니다. res/values/theme.xml 파일을 만듭니다.
그리고 아래의 코드를 넣습니다.

<resources>
    <style name="Theme.NoBackground" parent="android:Theme">
        <item name="android:windowBackground">@null</item>
    </style>
</resources>


이제 android:theme="@style/Theme.NoBackground" 속성을 <activity /> 나 <application />태그에 삽입하여 개발하고자하는 액티비티에 적용시킵니다.
MapView 나 WebView를 사용하거나 풀스크린 투명 뷰를 사용하는 애플리케이션을 개발한다면 매우 손쉽게 적용시킬 수 있습니다.

투명 뷰와 안드로이드 : 이 작업은 최적화 작업이 필요한데 안드로이드 UI 툴은 투명 자식객체로 숨겨진 뷰들을 다시 그리는 것을 방지할 만큼 똑똑하진 않기 때문입니다.
이 최적화 작업이 실행되지 않은 가장 주요한 이유는 안드로이드 애플리케이션에는 보통 투명 뷰가 없거나 아주 소수이기 때문입니다.
상황이 이렇다해도 최대한 이른 시기안에 이 최적화 작업을 진행하겠습니다. 좀 더 일찍 실행하지 못한 점이 죄송합니다.(번역자 주: 프레젠테이션에서 발표한 자료같음)

테마를 사용해서 윈도우의 백그라운드를 바꾸는 것 또한 액티비티의 스타트업 속도를 향상시킬 수 있습니다.
단, 텍스쳐나 로고를 이용한 커스텀 백그라운드를 사용하는 액티비티에만 적용됩니다.
아래 스크린샷에서 보이는 책장선반 애플리케이션이 좋은 보기입니다.






만약 이 애플리케이션의 XML이나 onCreate()메서드에서 그냥 나무 백그라운드를 지정해버린다면 사용자는 기본테마와 어두운 백그라운드를 보게 됩니다.
나무 텍스쳐(질감)은 context 뷰의 로드 후와 첫번째 레이아웃/그리기 작업이 끝난다음에만 나타나게 됩니다.
이런 작업을 보는 사용자는 애플리케이션이 불안하고 로딩하는데 시간이 오래 걸린다고 생각합니다.(실제로도 그렇습니다)
대신에 애플리케이션이 나무 백그라운드를 테마로 정의하고 애플리케이션이 시작되자마자 안드로이드 시스템이 이 설정을 적용시킨다면 사용자는 기본 테마를 보지 않게 되고
애플리케이션이 빠릿빠릿하고 바로 실행되어 빠르다는 인상을 갖게 됩니다.
메모리와 디스크 사용량을 줄이기 위해서는 res/drawable/background_shelf.xml 파일에 아래와 같이 백그라운드 타일을 정의합니다.

<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/shelf_panel"
    android:tileMode="repeat" />

이 Drawable 은 테마를 참조합니다.

<resources>
    <style name="Theme.Shelves" parent="android:Theme">
        <item name="android:windowBackground">@drawable/background_shelf</item>
        <item name="android:windowNoTitle">true</item>
    </style>
</resources>

Google Maps 애플리케이션에 위에서 보인 기법과 똑같은 기법이 사용되었습니다. 애플리케이션이 구동되면 사용자는 즉시 MapView의 타일들을 보게 됩니다.
테마는 MapView에서 타일을 로드하는 것과 똑같이 보이는 타일 백그라운드를 사용합니다.

가끔식 보면 최고의 기법들은 아주 간단합니다.
다음번에 투명 UI 혹은 커스텀 백그라운드를 사용하는 액티비티를 만들때는 윈도우의 백그라운드를 바꾸는 걸 기억하세요.
저작자 표시 비영리 동일 조건 변경 허락
신고