[Android Dev Study] - 앱 테마 만들기 #0에 이어서 Activity에 테마를 적용해 보겠다.
style에 테마 항목을 정의합니다. View ID가 없기 때문에 ID도 함께 정의합니다.
<item name="theme_status_bar" type="id"/> <item name="theme_action_bar" type="id"/> <item name="theme_tab_bar" type="id"/> <item name="theme_default_bg" type="id"/> <item name="theme_text_default" type="id"/> <item name="theme_text_dark" type="id"/> <item name="theme_text_light" type="id"/> <string name="thk_activity">activity</string> <string-array name="thk_activity_names"> <item>status_bar</item> <item>action_bar</item> <item>tab_bar</item> <item>default_bg</item> <item>text_default</item> <item>text_dark</item> <item>text_light</item> </string-array> <integer-array name="thk_activity_ids"> <item>@id/theme_status_bar</item> <item>@id/theme_action_bar</item> <item>@id/theme_tab_bar</item> <item>@id/theme_default_bg</item> <item>@id/theme_text_default</item> <item>@id/theme_text_dark</item> <item>@id/theme_text_light</item> </integer-array>
JSON에 테마 컬러를 만듭니다.
"activity" : { "status_bar": { "color" : "#5b4035" }, "action_bar": { "color" : "#6b4839" }, "tab_bar": { "color" : "#e0d4c8" }, "default_bg": { "color" : "#f2ede6" }, "text_default": { "color" : "#9a857c" }, "text_dark": { "color" : "#3f3429" }, "text_light": { "color" : "#694639" } },
테마 아이템 키를 만듭니다.
public static final ThemeItemKey ACTIVITY = new ThemeItemKey(R.string.thk_activity, R.array.thk_activity_names, R.array.thk_activity_ids, 0);
BaseActivity에서 테마를 적용합니다. View기반이 아니기 때문에 테마 데이타에서 color나 drawable을 얻어와서 개별적으로 적용합니다.
public static void applyBaseTheme(AppCompatActivity activity, boolean changeBgColor) { if (ThemeManager.getInstance().isDefaultTheme()) { return; } // status bar if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { int color = ThemeManager.getInstance().getColor(ACTIVITY, R.id.theme_status_bar, R.id.thk_color, 0); if (color != 0) { activity.getWindow().setStatusBarColor(color); } } // action bar ActionBar actionBar = activity.getSupportActionBar(); if (actionBar != null) { Drawable drawable = ThemeManager.getInstance().getDrawable(ACTIVITY, R.id.theme_action_bar, R.id.thk_background_drawable); if (drawable != null) { actionBar.setBackgroundDrawable(drawable); } else { int color = ThemeManager.getInstance().getColor(ACTIVITY, R.id.theme_action_bar, R.id.thk_color, 0); if (color != 0) { actionBar.setBackgroundDrawable(new ColorDrawable(color)); } } } if (changeBgColor) { int color = ThemeManager.getInstance().getColor(ACTIVITY, R.id.theme_default_bg, R.id.thk_color, 0); if (color != 0) { activity.findViewById(android.R.id.content).setBackgroundColor(color); } } }
네비게이션바 컬러는 빠트렸는데 간단히 키를 추가하여 아래 코드를 참고하여 적용 가능합니다.
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { getWindow().setNavigationBarColor(ContextCompat.getColor(this, R.color.colorPrimary)); }
colorPrimary, colorPrimaryDark, colorAccent의 컬러를 코드로 변경하는 방법은 찾지 못했다. 때문에 각 테마마다 style을 만들고 BaseActivity#onCreate에서 setTheme()를 이용해서 변경했다.
<color name="brownColorPrimary">#6b4839</color> <color name="brownColorPrimaryDark">#5b4035</color> <color name="brownColorAccent">#9a857c</color> <style name="AppTheme.Brown" parent="AppTheme"> <!-- Main theme colors --> <!-- your app branding color for the app bar --> <item name="colorPrimary">@color/brownColorPrimary</item> <!-- darker variant for the status bar and contextual app bars --> <item name="colorPrimaryDark">@color/brownColorPrimaryDark</item> <!-- theme UI controls like checkboxes and text fields --> <item name="colorAccent">@color/brownColorAccent</item> </style>
BaseActivity#onCreate에서 테마를 변경한다. 실제로 아래처럼 동작하는 것은 아니고 Theme에서 style 리소스 아이디를 얻어올 수 있도록 구현해야 합니다.
@Override protected void onCreate(Bundle savedInstanceState) { setTheme(R.style.AppTheme_Brown); super.onCreate(savedInstanceState); }