[안드로이드] 스타일과 테마

hee09·2022년 11월 4일
0

스타일과 테마

테마와 스타일은 모두 <style> 태그를 사용하고, 모두 Key-Value 형식으로 저장하면서 Key는 속성을 Value는 리소스를 나타내지만 사용 목적이 다릅니다. 스타일일과 테마의 개념과 적용하는 방법을 알아보며 차이점을 파악해보겠습니다.


Style

스타일은 View의 속성의 집합 입니다. 즉, 하나의 View를 위해서 속성들을 모아서 적용하는 것으로 레이아웃 파일 안에서 설정할 수 있는 모든 속성을 사용할 수 있습니다.

style 선언

<style name="Widget.Plaid.Button.InlineAction" parent="">
  <item name="android:gravity">center_horizontal</item>
  <item name="android:textAppearance">@style/TextAppearance.CommentAuthor</item>
  <item name="android:drawablePadding">@dimen/spacing_micro</item>
</style>
  • 스타일의 name 속성은 각 스타일을 유일하게 구별하는 속성입니다.
  • 스타일의 parent 속성은 상속을 의미합니다. 즉, parent 속성으로 지정하는 스타일의 속성들을 따르고, 만약 오버라이드하려는 속성이 있다면 하나의 item으로 선언하면 됩니다.
  • item은 레이아웃의 하나의 속성을 나타내고 itemname은 속성명, 값은 적용하려는 리소스를 의미합니다.

style 적용

<Button 
  style="@style/Widget.Plaid.Button.InlineAction"/>
  • 안드로이드에서 하나의 View는 하나의 스타일만을 적용할 수 있습니다.

스타일 적용 범위

스타일은 해당 스타일을 적용한 하나의 뷰에만 적용이 되고 그 자식 뷰들에게는 영향을 주지 않습니다. 예를 들어서, 세 개의 버튼을 가지고 있는 ViewGroup에 위의 InlineAction의 이름을 가진 스타일을 적용하더라도 자식 뷰인 세 개의 버튼에는 스타일이 적용되지 않습니다.

스타일을 사용하는 좋은 예시로는 여러 개의 View에 똑같이 적용해야하는 속성이 있을 경우 이를 일일히 모두 선언하는 것보다, 하나의 style을 만들고 각 view에 적용하는 것이 있습니다.


Theme

테마는 스타일, 레이아웃, 위젯 등에서 참조할 수 있는 명명된 리소스 집합을 정의합니다. 예를 들어 colorPrimary와 같은 이미 만들어진 이름을 리소스에 할당하는 것입니다.

theme 선언

<style name="Theme.Plaid" parent="">
  <item name="colorPrimary">@color/teal_500</item>
  <item name="colorSecondary">@color/pink_200</item>
  <item name="android:windowBackground">@color/white</item>
</style>

테마 속성은 개별적인 View에 고유한 속성이 아니라 앱에서 광범위하게 적용할 수 있는 값에 대한 의미론적인 명명된 포인터이기에 뷰 속성과는 다릅니다. 테마는 이렇게 명명된 리소스에 대한 구체적인 값을 제공합니다. 위의 예시에서는 colorPrimary 속성을 통해 이 테마의 기본 색상이 청록색임을 지정하고 있습니다.

  • 테마의 name 속성은 각 테마를 유일하게 구별하는 속성입니다.
  • 테마의 parent 속성은 상속을 의미합니다. 즉, parent 속성으로 지정하는 테마를 따르고, 만약 오버라이드하려는 속성이 있다면 하나의 item으로 선언하면 됩니다.

theme 적용

<!-- AndroidManifest.xml -->
<application 
  android:theme="@style/Theme.Plaid">
<activity 
  android:theme="@style/Theme.Plaid.About"/>

<!-- layout/foo.xml -->
<ConstraintLayout 
  android:theme="@style/Theme.Plaid.Foo">
  • 테마는 Context 객체를 가지고 있는 컴포넌트에 적용할 수 있습니다. 그 예시로 Application, Activity, Views/ViewGroup 등이 있습니다.
  • 테마는 스타일과 다르게 Views/ViewGroup에 적용하면 자식 View들도 테마가 적용됩니다.
  • 또한 기존 Context를 ContextThemeWrapper로 감싸서 레이아웃이아닌 코드에서 테마를 설정할 수 있습니다.
    • ContextThemeWrapper는 다른 context의 테마를 수정하거나 덮어씌울 수 있습니다.

테마 적용 범위

테마는 Context 프로퍼티를 통해 접근할 수 있으며, Application, Activity, View 또는 ViewGroup과 같이 Context를 가지고 있는 객체로부터 획득할 수 있습니다. 이 객체들은 트리 구조로 존재하는데, 만약 트리의 하나의 노드에서 테마를 적용하면 해당 노드의 자식 노드들은 모두 테마가 적용됩니다. 즉, 하나의 View에만 적용되는 스타일과는 다르게, 테마는 모든 View에 적용할 수 있습니다.

  • 위와 같이 트리 구조로 테마가 적용되는 행동은 레이아웃의 inflation 시간에 일어납니다. 따라서 Context의 setTheme 메서드 또는 Theme의 applyStyle 메서드는 레이아웃의 inflation이 일어나기 전에 호출해야 합니다.

참조 및 참고
Android Styling: themes vs styles
Android Styling: themes overlay
Using Context Theme Wrapper on Android

profile
되새기기 위해 기록

0개의 댓글