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