괴도군의 블로그

[Android]Theme , style은 무엇인가? 본문

#프로그래밍/Android

[Android]Theme , style은 무엇인가?

괴도군 2016. 6. 3. 13:30
반응형

안드로이드를 배우면서 잘이해가 되지않던부분이고.. 실무에서도 많은사람들이 모르고 넘어갈 수 있는부분이다.


간단하게 먼저 설명하고 시작하자면..


Theme는 앱의 전체 style을 지정하는 방식이다.


버튼, 다이얼로그 등 모든것들의 기본색부터 사이즈까지 다~ 나와있다.


style은 각 위젯들에 적용되는 속성의 모음이라 할 수 있다.


아래와같이 한줄만 넣어도 여러가지가 적용되는것과 같다.


테마별 위젯모양 스크린샷



Holo




Material





Platform.V14.AppCompat.Light







TextView에서 크기를 설정할때 style을 썼던적이 있다.


1
2
3
4
5
 <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="test"
        style="@style/TextAppearance.AppCompat.Large"/>
cs



그냥 크기가 커지니까 Large나 Small로 자주 썼는데.. 이게 뭔지 별생각도 사실 없었다..


한참뒤에나 깨달았고.. 글을 쓰는지금에서야 추적을 해보았다..


xml도 parent가 있고 상속의 개념이 있구나...


com.android.support.appcompat-v7/버전/res/values/values.xml  이 위치에 존재한다.

1
<style name="TextAppearance.AppCompat.Large" parent="Base.TextAppearance.AppCompat.Large"/>
cs


자 부모가 누군지 다시 추적한다..


1
2
3
4
<style name="Base.TextAppearance.AppCompat.Large">
        <item name="android:textSize">@dimen/abc_text_size_large_material</item>
        <item name="android:textColor">?android:attr/textColorPrimary</item>
</style>
cs


드디어 값이 나왔따.. textSize는 저 abc어쩌구에 적혀있겠구나!


1
2
3
<dimen name="abc_text_size_large_material">22sp</dimen>
 
<attr name="textColorPrimary" format="reference|color" />
cs


찾아보니.. 22sp 였구나.. (폰트 사이즈단위 sp , 참고:http://aroundck.tistory.com/2315)


textColorPrimary는 attr이고.. 이건 속성을 정할때 쓰는건데.. 했지만


?attr 이렇게 사용하는 구문은.. 테마에서 지정된 속성을 따라가라는 말이다.







그래서 테마를 추적하기 시작했다.


1
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
cs


현재 기본적용된 테마이다.


1
<style name="Theme.AppCompat.Light.DarkActionBar" parent="Base.Theme.AppCompat.Light.DarkActionBar"/>
cs


한단계 왔다.


1
2
3
4
5
6
7
8
9
10
11
<style name="Base.Theme.AppCompat.Light.DarkActionBar" parent="Base.Theme.AppCompat.Light">
        <item name="actionBarPopupTheme">@style/ThemeOverlay.AppCompat.Light</item>
        <item name="actionBarWidgetTheme">@null</item>
        <item name="actionBarTheme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
 
        <!-- Panel attributes -->
        <item name="listChoiceBackgroundIndicator">@drawable/abc_list_selector_holo_dark</item>
 
        <item name="colorPrimaryDark">@color/primary_dark_material_dark</item>
        <item name="colorPrimary">@color/primary_material_dark</item>
</style>
cs


뭔가 나오기 시작한다..


1
<style name="Base.Theme.AppCompat.Light" parent="Base.V7.Theme.AppCompat.Light">
cs


아직멀었따.


1
2
3
<style name="Base.V7.Theme.AppCompat.Light" parent="Platform.AppCompat.Light">
.....
</style>
cs


실제로 약 140라인정도 차지하면서 버튼, 다이얼로그,액션바등의 속성 기본값을 정해주고있다.

한번더 들어가보자..


1
2
3
<style name="Platform.AppCompat" parent="android:Theme">
....
</style>
cs


부모가 Theme인걸보니 거의 다온것같다. (Theme는 거의 모든속성의 기본값을 가지고있다. 400줄정도 된다)


window의 속성들도있고 찾던  textColorPrimary 를 발견했다.


1
2
<!-- Text colors -->
<item name="android:textColorPrimary">@color/abc_primary_text_material_light</item>
cs


중간에 이런식으로 되어있다.


결국 #de000000  약간 투명한 검정이다..



테스트앱의 AndroidManifest.xml파일이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.test.testapplication">
 
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
 
</manifest>
 
cs



테마가 application에서도 적용이 가능하고.. activity에서도 각각 테마를 적용할 수 있다.

둘다 적용한다면 액티비티가 더 아랫단이기에 중복되서 액티비티의 테마가 적용된다.


기본설정된 테마이다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<resources>
 
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
 
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>
 
</resources>
 
cs



이렇게 직접 항목을 지정하여 넣어주는것도 가능하다.


<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>


이 부분은.. 테마마다 NoActionBar가 존재하는데 거기의 옵션이다.


그리고.. 중요한것 하나더!


Theme. 


이렇게 테마가 점이 포함 되어있는데 이건 이것에 기반하여(상속하여) 테마를 선언하는것이다.



Theme.AppCompat.Light.DarkActionBar


앱에 기본적용된 테마인데..

Theme + Theme.AppCompat + Theme.AppCompat.Light + Theme.AppCompat.Light.DarkActionBar 인것이다.


중복되는부분은 맨 마지막에 선언한값으로 적용된다.


결론.

기존에 있는테마를 써도 되지만.. 이렇게 커스텀이 가능하다는것이다..


1
2
3
4
5
6
7
<style name="Theme.AppCompat.Light.NoActionBar.e">
 
</style>
    
<style name="e" parent="Theme.AppCompat.Light.NoActionBar">
        
</style>
cs

이 두개의 테마는 같은것이다.. 

그저 이름이 다른것일뿐...


그리고.. attr로 커스텀 속성을 만들어보신분이라면 알겠지만...

모든 속성값은 각 위젯클래스에서 처리를 해주기때문에 존재하는것이다.


예를들어 텍스트의 크기를 결정하는 testSize옵션을 TextView 클래스에서 처리를 해주고 있기때문에 사용이 되는것이다.


그래서 아무거나 내가 넣고싶은걸 넣는다고 되는게 아니다..


커스텀뷰를 제작해서 내가 만든 속성을 넣는거라면 되겠습니다.


반응형
Comments