ContextThemeWrapper.java revision cc2a1d48a0e4134823c940291f5db6fd9f2ae9b3
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.view; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19417ee5ba89f7e0fe5efd34fce74bf1ee5923d976Tor Norbyeimport android.annotation.StyleRes; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContextWrapper; 22756220bd1912535840388a6743830d2e59ad4964Dianne Hackbornimport android.content.res.Configuration; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A ContextWrapper that allows you to modify the theme from what is in the 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * wrapped context. 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class ContextThemeWrapper extends ContextWrapper { 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mThemeResource; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Resources.Theme mTheme; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private LayoutInflater mInflater; 33756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn private Configuration mOverrideConfiguration; 34756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn private Resources mResources; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ContextThemeWrapper() { 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(null); 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette 40417ee5ba89f7e0fe5efd34fce74bf1ee5923d976Tor Norbye public ContextThemeWrapper(Context base, @StyleRes int themeResId) { 41b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette super(base); 42b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette mThemeResource = themeResId; 43b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette } 44b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette 45b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette public ContextThemeWrapper(Context base, Resources.Theme theme) { 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(base); 47b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette mTheme = theme; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette @Override 51b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette protected void attachBaseContext(Context newBase) { 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.attachBaseContext(newBase); 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 54756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn 55756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn /** 56756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn * Call to set an "override configuration" on this context -- this is 57756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn * a configuration that replies one or more values of the standard 58756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn * configuration that is applied to the context. See 59756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn * {@link Context#createConfigurationContext(Configuration)} for more 60756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn * information. 61756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn * 62756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn * <p>This method can only be called once, and must be called before any 63756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn * calls to {@link #getResources()} are made. 64756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn */ 65756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn public void applyOverrideConfiguration(Configuration overrideConfiguration) { 66756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn if (mResources != null) { 67756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn throw new IllegalStateException("getResources() has already been called"); 68756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn } 69756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn if (mOverrideConfiguration != null) { 70756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn throw new IllegalStateException("Override configuration has already been set"); 71756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn } 72756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn mOverrideConfiguration = new Configuration(overrideConfiguration); 73756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn } 74756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn 75756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn @Override 76756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn public Resources getResources() { 77756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn if (mResources != null) { 78756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn return mResources; 79756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn } 80756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn if (mOverrideConfiguration == null) { 81756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn mResources = super.getResources(); 82756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn return mResources; 83756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn } else { 84756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn Context resc = createConfigurationContext(mOverrideConfiguration); 85756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn mResources = resc.getResources(); 86756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn return mResources; 87756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn } 88756220bd1912535840388a6743830d2e59ad4964Dianne Hackborn } 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 90cc2a1d48a0e4134823c940291f5db6fd9f2ae9b3Alan Viverette @Override 91cc2a1d48a0e4134823c940291f5db6fd9f2ae9b3Alan Viverette public void setTheme(int resid) { 92cc2a1d48a0e4134823c940291f5db6fd9f2ae9b3Alan Viverette if (mThemeResource != resid) { 93cc2a1d48a0e4134823c940291f5db6fd9f2ae9b3Alan Viverette mThemeResource = resid; 94cc2a1d48a0e4134823c940291f5db6fd9f2ae9b3Alan Viverette initializeTheme(); 95cc2a1d48a0e4134823c940291f5db6fd9f2ae9b3Alan Viverette } 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 98247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn /** @hide */ 99247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn @Override 100247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn public int getThemeResId() { 101247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn return mThemeResource; 102247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn } 103247fe74c934cb3fba85aae7e051a8044f460fb11Dianne Hackborn 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override public Resources.Theme getTheme() { 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTheme != null) { 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mTheme; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1095effd7e89f83824ac8982a6cbcebbf5cc331e436Alan Viverette mThemeResource = Resources.selectDefaultTheme(mThemeResource, 110d922ae01ca99a2b6d39a9393f86776a1d10ebd14Dianne Hackborn getApplicationInfo().targetSdkVersion); 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project initializeTheme(); 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mTheme; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override public Object getSystemService(String name) { 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LAYOUT_INFLATER_SERVICE.equals(name)) { 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mInflater == null) { 119ebb9f3a1a3cb405dac7f98815b37c198c65739cdFabrice Di Meglio mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mInflater; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 123ebb9f3a1a3cb405dac7f98815b37c198c65739cdFabrice Di Meglio return getBaseContext().getSystemService(name); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called by {@link #setTheme} and {@link #getTheme} to apply a theme 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * resource to the current Theme object. Can override to change the 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * default (simple) behavior. This method will not be called in multiple 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * threads simultaneously. 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param theme The Theme object being modified. 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param resid The theme style resource being applied to <var>theme</var>. 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param first Set to true if this is the first time a style is being 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * applied to <var>theme</var>. 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) { 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project theme.applyStyle(resid, true); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void initializeTheme() { 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean first = mTheme == null; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (first) { 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTheme = getResources().newTheme(); 145ebb9f3a1a3cb405dac7f98815b37c198c65739cdFabrice Di Meglio Resources.Theme theme = getBaseContext().getTheme(); 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (theme != null) { 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTheme.setTo(theme); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project onApplyThemeResource(mTheme, mThemeResource, first); 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 154