1/* 2 * Copyright (C) 2006 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.view; 18 19import android.content.Context; 20import android.content.ContextWrapper; 21import android.content.res.Resources; 22import android.os.Build; 23 24/** 25 * A ContextWrapper that allows you to modify the theme from what is in the 26 * wrapped context. 27 */ 28public class ContextThemeWrapper extends ContextWrapper { 29 private Context mBase; 30 private int mThemeResource; 31 private Resources.Theme mTheme; 32 private LayoutInflater mInflater; 33 34 public ContextThemeWrapper() { 35 super(null); 36 } 37 38 public ContextThemeWrapper(Context base, int themeres) { 39 super(base); 40 mBase = base; 41 mThemeResource = themeres; 42 } 43 44 @Override protected void attachBaseContext(Context newBase) { 45 super.attachBaseContext(newBase); 46 mBase = newBase; 47 } 48 49 @Override public void setTheme(int resid) { 50 mThemeResource = resid; 51 initializeTheme(); 52 } 53 54 /** @hide */ 55 @Override 56 public int getThemeResId() { 57 return mThemeResource; 58 } 59 60 @Override public Resources.Theme getTheme() { 61 if (mTheme != null) { 62 return mTheme; 63 } 64 65 mThemeResource = Resources.selectDefaultTheme(mThemeResource, 66 getApplicationInfo().targetSdkVersion); 67 initializeTheme(); 68 69 return mTheme; 70 } 71 72 @Override public Object getSystemService(String name) { 73 if (LAYOUT_INFLATER_SERVICE.equals(name)) { 74 if (mInflater == null) { 75 mInflater = LayoutInflater.from(mBase).cloneInContext(this); 76 } 77 return mInflater; 78 } 79 return mBase.getSystemService(name); 80 } 81 82 /** 83 * Called by {@link #setTheme} and {@link #getTheme} to apply a theme 84 * resource to the current Theme object. Can override to change the 85 * default (simple) behavior. This method will not be called in multiple 86 * threads simultaneously. 87 * 88 * @param theme The Theme object being modified. 89 * @param resid The theme style resource being applied to <var>theme</var>. 90 * @param first Set to true if this is the first time a style is being 91 * applied to <var>theme</var>. 92 */ 93 protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) { 94 theme.applyStyle(resid, true); 95 } 96 97 private void initializeTheme() { 98 final boolean first = mTheme == null; 99 if (first) { 100 mTheme = getResources().newTheme(); 101 Resources.Theme theme = mBase.getTheme(); 102 if (theme != null) { 103 mTheme.setTo(theme); 104 } 105 } 106 onApplyThemeResource(mTheme, mThemeResource, first); 107 } 108} 109 110