ContextThemeWrapper.java revision f933672168f6deff5e3636584bec735416b5a93b
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.support.v7.internal.view; 18 19import android.content.Context; 20import android.content.ContextWrapper; 21import android.content.res.Resources; 22import android.support.annotation.StyleRes; 23import android.support.v7.appcompat.R; 24import android.view.LayoutInflater; 25 26/** 27 * A ContextWrapper that allows you to modify the theme from what is in the 28 * wrapped context. 29 * 30 * @hide 31 */ 32public class ContextThemeWrapper extends ContextWrapper { 33 private int mThemeResource; 34 private Resources.Theme mTheme; 35 private LayoutInflater mInflater; 36 37 public ContextThemeWrapper(Context base, @StyleRes int themeResId) { 38 super(base); 39 mThemeResource = themeResId; 40 } 41 42 public ContextThemeWrapper(Context base, Resources.Theme theme) { 43 super(base); 44 mTheme = theme; 45 } 46 47 @Override 48 public void setTheme(int resid) { 49 if (mThemeResource != resid) { 50 mThemeResource = resid; 51 initializeTheme(); 52 } 53 } 54 55 public int getThemeResId() { 56 return mThemeResource; 57 } 58 59 @Override 60 public Resources.Theme getTheme() { 61 if (mTheme != null) { 62 return mTheme; 63 } 64 65 if (mThemeResource == 0) { 66 mThemeResource = R.style.Theme_AppCompat_Light; 67 } 68 initializeTheme(); 69 70 return mTheme; 71 } 72 73 @Override 74 public Object getSystemService(String name) { 75 if (LAYOUT_INFLATER_SERVICE.equals(name)) { 76 if (mInflater == null) { 77 mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this); 78 } 79 return mInflater; 80 } 81 return getBaseContext().getSystemService(name); 82 } 83 84 /** 85 * Called by {@link #setTheme} and {@link #getTheme} to apply a theme 86 * resource to the current Theme object. Can override to change the 87 * default (simple) behavior. This method will not be called in multiple 88 * threads simultaneously. 89 * 90 * @param theme The Theme object being modified. 91 * @param resid The theme style resource being applied to <var>theme</var>. 92 * @param first Set to true if this is the first time a style is being 93 * applied to <var>theme</var>. 94 */ 95 protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) { 96 theme.applyStyle(resid, true); 97 } 98 99 private void initializeTheme() { 100 final boolean first = mTheme == null; 101 if (first) { 102 mTheme = getResources().newTheme(); 103 Resources.Theme theme = getBaseContext().getTheme(); 104 if (theme != null) { 105 mTheme.setTo(theme); 106 } 107 } 108 onApplyThemeResource(mTheme, mThemeResource, first); 109 } 110} 111 112