ActionBarActivityDelegate.java revision 2bc5191a8cc331b404724759a015949a4b5499fb
1/*
2 * Copyright (C) 2013 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.content.Context;
20import android.content.pm.ActivityInfo;
21import android.content.pm.PackageManager;
22import android.content.res.Configuration;
23import android.content.res.TypedArray;
24import android.os.Build;
25import android.os.Bundle;
26import android.support.v4.app.ActionBarDrawerToggle;
27import android.support.v4.app.NavUtils;
28import android.support.v7.appcompat.R;
29import android.support.v7.internal.view.SupportMenuInflater;
30import android.support.v7.view.ActionMode;
31import android.util.Log;
32import android.view.Menu;
33import android.view.MenuInflater;
34import android.view.MenuItem;
35import android.view.View;
36import android.view.ViewGroup;
37
38abstract class ActionBarActivityDelegate {
39
40    static final String METADATA_UI_OPTIONS = "android.support.UI_OPTIONS";
41    static final String UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW = "splitActionBarWhenNarrow";
42
43    private static final String TAG = "ActionBarActivityDelegate";
44
45    static ActionBarActivityDelegate createDelegate(ActionBarActivity activity) {
46        final int version = Build.VERSION.SDK_INT;
47        if (version >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
48            return new ActionBarActivityDelegateICS(activity);
49        } else if (version >= Build.VERSION_CODES.HONEYCOMB) {
50            return new ActionBarActivityDelegateHC(activity);
51        } else {
52            return new ActionBarActivityDelegateBase(activity);
53        }
54    }
55
56    final ActionBarActivity mActivity;
57
58    private ActionBar mActionBar;
59    private MenuInflater mMenuInflater;
60
61    // true if this activity has an action bar.
62    boolean mHasActionBar;
63    // true if this activity's action bar overlays other activity content.
64    boolean mOverlayActionBar;
65
66    private boolean mEnableDefaultActionBarUp;
67
68    ActionBarActivityDelegate(ActionBarActivity activity) {
69        mActivity = activity;
70    }
71
72    abstract ActionBar createSupportActionBar();
73
74    final ActionBar getSupportActionBar() {
75        // The Action Bar should be lazily created as mHasActionBar or mOverlayActionBar
76        // could change after onCreate
77        if (mHasActionBar || mOverlayActionBar) {
78            if (mActionBar == null) {
79                mActionBar = createSupportActionBar();
80
81                if (mEnableDefaultActionBarUp) {
82                    mActionBar.setDisplayHomeAsUpEnabled(true);
83                }
84            }
85        } else {
86            // If we're not set to have a Action Bar, null it just in case it's been set
87            mActionBar = null;
88        }
89        return mActionBar;
90    }
91
92    MenuInflater getMenuInflater() {
93        if (mMenuInflater == null) {
94            ActionBar ab = getSupportActionBar();
95            if (ab != null) {
96                mMenuInflater = new SupportMenuInflater(ab.getThemedContext());
97            } else {
98                mMenuInflater = new SupportMenuInflater(mActivity);
99            }
100        }
101        return mMenuInflater;
102    }
103
104    void onCreate(Bundle savedInstanceState) {
105        TypedArray a = mActivity.obtainStyledAttributes(R.styleable.ActionBarWindow);
106
107        if (!a.hasValue(R.styleable.ActionBarWindow_windowActionBar)) {
108            a.recycle();
109            throw new IllegalStateException(
110                    "You need to use a Theme.AppCompat theme (or descendant) with this activity.");
111        }
112
113        mHasActionBar = a.getBoolean(R.styleable.ActionBarWindow_windowActionBar, false);
114        mOverlayActionBar = a.getBoolean(R.styleable.ActionBarWindow_windowActionBarOverlay, false);
115        a.recycle();
116
117        if (NavUtils.getParentActivityName(mActivity) != null) {
118            if (mActionBar == null) {
119                mEnableDefaultActionBarUp = true;
120            } else {
121                mActionBar.setDisplayHomeAsUpEnabled(true);
122            }
123        }
124    }
125
126    abstract void onConfigurationChanged(Configuration newConfig);
127
128    abstract void onStop();
129
130    abstract void onPostResume();
131
132    abstract void setContentView(View v);
133
134    abstract void setContentView(int resId);
135
136    abstract void setContentView(View v, ViewGroup.LayoutParams lp);
137
138    abstract void addContentView(View v, ViewGroup.LayoutParams lp);
139
140    abstract void onTitleChanged(CharSequence title);
141
142    abstract void supportInvalidateOptionsMenu();
143
144    abstract boolean supportRequestWindowFeature(int featureId);
145
146    // Methods used to create and respond to options menu
147    abstract View onCreatePanelView(int featureId);
148
149    abstract boolean onPreparePanel(int featureId, View view, Menu menu);
150
151    boolean onPrepareOptionsPanel(View view, Menu menu) {
152        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
153            // Call straight through to onPrepareOptionsMenu, bypassing super.onPreparePanel().
154            // This is because Activity.onPreparePanel() on <v4.1 calls menu.hasVisibleItems(),
155            // which interferes with the initially invisible items.
156            return mActivity.onPrepareOptionsMenu(menu);
157        }
158        return mActivity.superOnPrepareOptionsPanel(view, menu);
159    }
160
161    abstract boolean onCreatePanelMenu(int featureId, Menu menu);
162
163    abstract boolean onMenuItemSelected(int featureId, MenuItem item);
164
165    abstract boolean onBackPressed();
166
167    abstract ActionMode startSupportActionMode(ActionMode.Callback callback);
168
169    abstract void setSupportProgressBarVisibility(boolean visible);
170
171    abstract void setSupportProgressBarIndeterminateVisibility(boolean visible);
172
173    abstract void setSupportProgressBarIndeterminate(boolean indeterminate);
174
175    abstract void setSupportProgress(int progress);
176
177    abstract ActionBarDrawerToggle.Delegate getDrawerToggleDelegate();
178
179    protected final String getUiOptionsFromMetadata() {
180        try {
181            PackageManager pm = mActivity.getPackageManager();
182            ActivityInfo info = pm.getActivityInfo(mActivity.getComponentName(),
183                    PackageManager.GET_META_DATA);
184
185            String uiOptions = null;
186            if (info.metaData != null) {
187                uiOptions = info.metaData.getString(METADATA_UI_OPTIONS);
188            }
189            return uiOptions;
190        } catch (PackageManager.NameNotFoundException e) {
191            Log.e(TAG, "getUiOptionsFromMetadata: Activity '" + mActivity.getClass()
192                    .getSimpleName() + "' not in manifest");
193            return null;
194        }
195    }
196
197    protected final Context getActionBarThemedContext() {
198        Context context = mActivity;
199
200        // If we have an action bar, initialize the menu with a context themed from it.
201        ActionBar ab = getSupportActionBar();
202        if (ab != null) {
203            context = ab.getThemedContext();
204        }
205        return context;
206    }
207}
208