blob: 6c733f9e11a88e02b5d7226e2af0df0fc1c282ec [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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;
Dianne Hackborn756220b2012-08-14 16:45:30 -070021import android.content.res.Configuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.content.res.Resources;
Dianne Hackbornb35cd542011-01-04 21:30:53 -080023import android.os.Build;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024
25/**
26 * A ContextWrapper that allows you to modify the theme from what is in the
27 * wrapped context.
28 */
29public class ContextThemeWrapper extends ContextWrapper {
30 private Context mBase;
31 private int mThemeResource;
32 private Resources.Theme mTheme;
33 private LayoutInflater mInflater;
Dianne Hackborn756220b2012-08-14 16:45:30 -070034 private Configuration mOverrideConfiguration;
35 private Resources mResources;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036
37 public ContextThemeWrapper() {
38 super(null);
39 }
40
41 public ContextThemeWrapper(Context base, int themeres) {
42 super(base);
43 mBase = base;
44 mThemeResource = themeres;
45 }
46
47 @Override protected void attachBaseContext(Context newBase) {
48 super.attachBaseContext(newBase);
49 mBase = newBase;
50 }
Dianne Hackborn756220b2012-08-14 16:45:30 -070051
52 /**
53 * Call to set an "override configuration" on this context -- this is
54 * a configuration that replies one or more values of the standard
55 * configuration that is applied to the context. See
56 * {@link Context#createConfigurationContext(Configuration)} for more
57 * information.
58 *
59 * <p>This method can only be called once, and must be called before any
60 * calls to {@link #getResources()} are made.
61 */
62 public void applyOverrideConfiguration(Configuration overrideConfiguration) {
63 if (mResources != null) {
64 throw new IllegalStateException("getResources() has already been called");
65 }
66 if (mOverrideConfiguration != null) {
67 throw new IllegalStateException("Override configuration has already been set");
68 }
69 mOverrideConfiguration = new Configuration(overrideConfiguration);
70 }
71
72 @Override
73 public Resources getResources() {
74 if (mResources != null) {
75 return mResources;
76 }
77 if (mOverrideConfiguration == null) {
78 mResources = super.getResources();
79 return mResources;
80 } else {
81 Context resc = createConfigurationContext(mOverrideConfiguration);
82 mResources = resc.getResources();
83 return mResources;
84 }
85 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086
87 @Override public void setTheme(int resid) {
88 mThemeResource = resid;
89 initializeTheme();
90 }
91
Dianne Hackborn247fe742011-01-08 17:25:57 -080092 /** @hide */
93 @Override
94 public int getThemeResId() {
95 return mThemeResource;
96 }
97
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 @Override public Resources.Theme getTheme() {
99 if (mTheme != null) {
100 return mTheme;
101 }
102
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800103 mThemeResource = Resources.selectDefaultTheme(mThemeResource,
104 getApplicationInfo().targetSdkVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 initializeTheme();
106
107 return mTheme;
108 }
109
110 @Override public Object getSystemService(String name) {
111 if (LAYOUT_INFLATER_SERVICE.equals(name)) {
112 if (mInflater == null) {
113 mInflater = LayoutInflater.from(mBase).cloneInContext(this);
114 }
115 return mInflater;
116 }
117 return mBase.getSystemService(name);
118 }
119
120 /**
121 * Called by {@link #setTheme} and {@link #getTheme} to apply a theme
122 * resource to the current Theme object. Can override to change the
123 * default (simple) behavior. This method will not be called in multiple
124 * threads simultaneously.
125 *
126 * @param theme The Theme object being modified.
127 * @param resid The theme style resource being applied to <var>theme</var>.
128 * @param first Set to true if this is the first time a style is being
129 * applied to <var>theme</var>.
130 */
131 protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) {
132 theme.applyStyle(resid, true);
133 }
134
135 private void initializeTheme() {
136 final boolean first = mTheme == null;
137 if (first) {
138 mTheme = getResources().newTheme();
139 Resources.Theme theme = mBase.getTheme();
140 if (theme != null) {
141 mTheme.setTo(theme);
142 }
143 }
144 onApplyThemeResource(mTheme, mThemeResource, first);
145 }
146}
147