ActionBarActivity.java revision 3954d59cb6073615ead9dd34cbdba9e16b8c5b6f
1/*
2 * Copyright (C) 2012 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.app;
18
19import android.app.Activity;
20import android.content.res.Configuration;
21import android.content.res.TypedArray;
22import android.os.Build;
23import android.os.Bundle;
24import android.support.v4.app.FragmentActivity;
25import android.support.v4.view.WindowCompat;
26import android.support.v7.appcompat.R;
27import android.support.v7.view.MenuInflater;
28import android.support.v7.view.MenuItem;
29import android.support.v7.internal.view.SupportMenuInflater;
30import android.view.View;
31import android.view.ViewGroup;
32import android.view.Window;
33
34/**
35 * Base class for activities that use the support library action bar features.
36 */
37public class ActionBarActivity extends FragmentActivity implements ActionBar.Callback {
38    ActionBarActivityDelegate mImpl;
39    ActionBar mActionBar;
40    MenuInflater mMenuInflater;
41
42    // true if the compatibility implementation has installed a window sub-decor layout.
43    boolean mSubDecorInstalled;
44
45    // true if this activity has an action bar.
46    boolean mHasActionBar;
47
48    // true if this activity's action bar overlays other activity content.
49    boolean mOverlayActionBar;
50
51    /**
52     * Support library version of {@link Activity#getActionBar}.
53     *
54     * <p>Retrieve a reference to this activity's ActionBar.
55     *
56     * @return The Activity's ActionBar, or null if it does not have one.
57     */
58    public ActionBar getSupportActionBar() {
59        // The Action Bar should be lazily created as mHasActionBar or mOverlayActionBar
60        // could change after onCreate
61        if (mHasActionBar || mOverlayActionBar) {
62            if (mActionBar == null) {
63                mActionBar = mImpl.createSupportActionBar();
64            }
65        } else {
66            // If we're not set to have a Action Bar, null it just in case it's been set
67            mActionBar = null;
68        }
69        return mActionBar;
70    }
71
72    /**
73     * Support library version of {@link Activity#getMenuInflater}.
74     *
75     * <p>Returns a {@link MenuInflater} with this context.
76     *
77     * @return The Activity's menu inflater.
78     */
79    public MenuInflater getSupportMenuInflater() {
80        if (mMenuInflater == null) {
81            mMenuInflater = new SupportMenuInflater(this);
82        }
83        return mMenuInflater;
84    }
85
86    @Override
87    public void setContentView(int layoutResID) {
88        mImpl.setContentView(layoutResID);
89    }
90
91    @Override
92    public void setContentView(View view) {
93        mImpl.setContentView(view);
94    }
95
96    @Override
97    public void setContentView(View view, ViewGroup.LayoutParams params) {
98        mImpl.setContentView(view, params);
99    }
100
101    @Override
102    protected void onCreate(Bundle savedInstanceState) {
103        super.onCreate(savedInstanceState);
104
105        final int version = Build.VERSION.SDK_INT;
106        if (version >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
107            mImpl = new ActionBarActivityDelegateICS(this);
108        } else if (version >= Build.VERSION_CODES.HONEYCOMB) {
109            mImpl = new ActionBarActivityDelegateHC(this);
110        } else {
111            mImpl = new ActionBarActivityDelegateCompat(this);
112        }
113
114        TypedArray a = obtainStyledAttributes(R.styleable.ActionBarWindow);
115        mHasActionBar = a.getBoolean(R.styleable.ActionBarWindow_windowActionBar, false);
116        mOverlayActionBar = a.getBoolean(R.styleable.ActionBarWindow_windowActionBarOverlay, false);
117        a.recycle();
118
119        mImpl.onCreate(savedInstanceState);
120    }
121
122    @Override
123    protected void onPostCreate(Bundle savedInstanceState) {
124        super.onPostCreate(savedInstanceState);
125        mImpl.onPostCreate(savedInstanceState);
126    }
127
128    @Override
129    public void onConfigurationChanged(Configuration newConfig) {
130        super.onConfigurationChanged(newConfig);
131        mImpl.onConfigurationChanged(newConfig);
132    }
133
134    @Override
135    public boolean onCreatePanelMenu(int featureId, android.view.Menu frameworkMenu) {
136        return mImpl.onCreatePanelMenu(featureId, frameworkMenu);
137    }
138
139    @Override
140    public boolean onPreparePanel(int featureId, View view, android.view.Menu menu) {
141        return mImpl.onPreparePanel(featureId, view, menu);
142    }
143
144    @Override
145    public View onCreatePanelView(int featureId) {
146        if (featureId == Window.FEATURE_OPTIONS_PANEL)
147            return mImpl.onCreatePanelView(featureId);
148        else {
149            return super.onCreatePanelView(featureId);
150        }
151    }
152
153    @Override
154    public boolean onMenuItemSelected(int featureId, android.view.MenuItem item) {
155        if (mImpl.onMenuItemSelected(featureId, item)) {
156            return true;
157        }
158        return super.onMenuItemSelected(featureId, item);
159    }
160
161    @Override
162    protected void onTitleChanged(CharSequence title, int color) {
163        super.onTitleChanged(title, color);
164        mImpl.setTitle(title);
165    }
166
167    /**
168     * Enable extended support library window features.
169     * <p>
170     * This is a convenience for calling
171     * {@link android.view.Window#requestFeature getWindow().requestFeature()}.
172     * </p>
173     *
174     * @param featureId The desired feature as defined in
175     * {@link android.view.Window} or {@link WindowCompat}.
176     * @return Returns true if the requested feature is supported and now enabled.
177     *
178     * @see android.app.Activity#requestWindowFeature
179     * @see android.view.Window#requestFeature
180     */
181    public boolean supportRequestWindowFeature(int featureId) {
182        return mImpl.requestWindowFeature(featureId);
183    }
184
185    @Override
186    public void supportInvalidateOptionsMenu() {
187        // Only call up to super on HC+, mImpl will handle otherwise
188        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
189            super.supportInvalidateOptionsMenu();
190        }
191        mImpl.supportInvalidateOptionsMenu();
192    }
193
194    /**
195     * Support library version of {@link Activity#onPrepareOptionsMenu}.
196     *
197     * <p>Prepare the Screen's standard options menu to be displayed.  This is
198     * called right before the menu is shown, every time it is shown.  You can
199     * use this method to efficiently enable/disable items or otherwise
200     * dynamically modify the contents.
201     *
202     * <p>The default implementation updates the system menu items based on the
203     * activity's state.  Deriving classes should always call through to the
204     * base class implementation.
205     *
206     * @param menu The options menu as last shown or first initialized by
207     *             onCreateSupportOptionsMenu().
208     *
209     * @return You must return true for the menu to be displayed;
210     *         if you return false it will not be shown.
211     *
212     * @see #onCreateSupportOptionsMenu
213     */
214    public boolean onPrepareSupportOptionsMenu(android.support.v7.view.Menu menu) {
215        return true;
216    }
217
218    /**
219     * Support library version of {@link Activity#onCreateOptionsMenu}.
220     *
221     * <p>Initialize the contents of the Activity's standard options menu.  You
222     * should place your menu items in to <var>menu</var>.
223     *
224     * <p>This is only called once, the first time the options menu is
225     * displayed.  To update the menu every time it is displayed, see
226     * {@link #onPrepareSupportOptionsMenu}.
227     *
228     * <p>The default implementation populates the menu with standard system
229     * menu items.  These are placed in the {@link android.support.v7.view.Menu#CATEGORY_SYSTEM}
230     * group so that they will be correctly ordered with application-defined menu items.
231     * Deriving classes should always call through to the base implementation.
232     *
233     * <p>You can safely hold on to <var>menu</var> (and any items created
234     * from it), making modifications to it as desired, until the next
235     * time onCreateSupportOptionsMenu() is called.
236     *
237     * <p>When you add items to the menu, you can implement the Activity's
238     * {@link #onSupportOptionsItemSelected} method to handle them there.
239     *
240     * @param menu The options menu in which you place your items.
241     *
242     * @return You must return true for the menu to be displayed;
243     *         if you return false it will not be shown.
244     *
245     * @see #onPrepareSupportOptionsMenu
246     * @see #onSupportOptionsItemSelected
247     */
248    public boolean onCreateSupportOptionsMenu(android.support.v7.view.Menu menu) {
249        return true;
250    }
251
252    /**
253     * Support library version of {@link Activity#onOptionsItemSelected}.
254     *
255     * <p>This hook is called whenever an item in your options menu is selected.
256     * The default implementation simply returns false to have the normal
257     * processing happen (calling the item's Runnable or sending a message to
258     * its Handler as appropriate).  You can use this method for any items
259     * for which you would like to do processing without those other
260     * facilities.
261     *
262     * <p>Derived classes should call through to the base class for it to
263     * perform the default menu handling.</p>
264     *
265     * @param item The menu item that was selected.
266     *
267     * @return boolean Return false to allow normal menu processing to
268     *         proceed, true to consume it here.
269     *
270     * @see #onPrepareSupportOptionsMenu
271     * @see #onCreateSupportOptionsMenu
272     */
273    public boolean onSupportOptionsItemSelected(android.support.v7.view.MenuItem item) {
274        return false;
275    }
276
277    /**
278     * Support library version of {@link Activity#onMenuItemSelected}.
279     *
280     * <p>Default implementation of {@link android.view.Window.Callback#onMenuItemSelected}
281     * for activities.  This calls through to the new {@link #onSupportOptionsItemSelected}
282     * method for the {@link android.view.Window#FEATURE_OPTIONS_PANEL}
283     * panel, so that subclasses of Activity don't need to deal with feature codes.
284     */
285    public boolean onSupportMenuItemSelected(int featureId, MenuItem item) {
286        return false;
287    }
288
289    void superSetContentView(int resId) {
290        super.setContentView(resId);
291    }
292
293    void superSetContentView(View v) {
294        super.setContentView(v);
295    }
296
297    void superSetContentView(View v, ViewGroup.LayoutParams lp) {
298        super.setContentView(v, lp);
299    }
300
301    void superAddContentView(View v, ViewGroup.LayoutParams lp) {
302        super.addContentView(v, lp);
303    }
304
305    boolean superOnCreatePanelMenu(int featureId, android.view.Menu frameworkMenu) {
306        return super.onCreatePanelMenu(featureId, frameworkMenu);
307    }
308
309    boolean superOnPreparePanelMenu(int featureId, View view, android.view.Menu menu) {
310        return super.onPreparePanel(featureId, view, menu);
311    }
312
313}
314