13954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes/* 23954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * Copyright (C) 2013 The Android Open Source Project 33954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * 43954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * Licensed under the Apache License, Version 2.0 (the "License"); 53954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * you may not use this file except in compliance with the License. 63954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * You may obtain a copy of the License at 73954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * 83954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * http://www.apache.org/licenses/LICENSE-2.0 93954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * 103954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * Unless required by applicable law or agreed to in writing, software 113954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * distributed under the License is distributed on an "AS IS" BASIS, 123954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * See the License for the specific language governing permissions and 143954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * limitations under the License. 153954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes */ 163954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 173954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banespackage android.support.v7.app; 183954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 19d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banesimport android.content.Context; 203954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banesimport android.content.pm.ActivityInfo; 213954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banesimport android.content.pm.PackageManager; 223954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banesimport android.content.res.Configuration; 235a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banesimport android.content.res.TypedArray; 245a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banesimport android.os.Build; 253954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banesimport android.os.Bundle; 2645d973fcc4c43f5ea00cddd3d9b947d9e8d8fc4eChris Banesimport android.support.v4.app.ActionBarDrawerToggle; 27bb994e828a647d6ca3c2480293e7a6e3a4c19952Chris Banesimport android.support.v4.app.NavUtils; 285a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banesimport android.support.v7.appcompat.R; 295a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banesimport android.support.v7.internal.view.SupportMenuInflater; 30d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banesimport android.support.v7.view.ActionMode; 313954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banesimport android.util.Log; 3230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.Menu; 3330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.MenuInflater; 3430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.MenuItem; 353954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banesimport android.view.View; 363954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banesimport android.view.ViewGroup; 373954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 383954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banesabstract class ActionBarActivityDelegate { 393954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 403954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes static final String METADATA_UI_OPTIONS = "android.support.UI_OPTIONS"; 413954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes static final String UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW = "splitActionBarWhenNarrow"; 423954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 433954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes private static final String TAG = "ActionBarActivityDelegate"; 443954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 455a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes static ActionBarActivityDelegate createDelegate(ActionBarActivity activity) { 465a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes final int version = Build.VERSION.SDK_INT; 478fcdb874200960138b32eb3b276a801f619b69b1Chris Banes if (version >= Build.VERSION_CODES.JELLY_BEAN) { 488fcdb874200960138b32eb3b276a801f619b69b1Chris Banes return new ActionBarActivityDelegateJB(activity); 498fcdb874200960138b32eb3b276a801f619b69b1Chris Banes } else if (version >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 505a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes return new ActionBarActivityDelegateICS(activity); 518123e4b3d19031e34a60c0db202f0b3d100eb9d8Chris Banes } else if (version >= Build.VERSION_CODES.HONEYCOMB) { 528123e4b3d19031e34a60c0db202f0b3d100eb9d8Chris Banes return new ActionBarActivityDelegateHC(activity); 535a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes } else { 54f2b7cd67036d78fd5b487b0a2dab28aee11d9c88Adam Powell return new ActionBarActivityDelegateBase(activity); 555a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes } 565a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes } 575a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes 583954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes final ActionBarActivity mActivity; 593954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 605a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes private ActionBar mActionBar; 615a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes private MenuInflater mMenuInflater; 625a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes 635a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes // true if this activity has an action bar. 645a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes boolean mHasActionBar; 655a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes // true if this activity's action bar overlays other activity content. 665a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes boolean mOverlayActionBar; 675a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes 68bb994e828a647d6ca3c2480293e7a6e3a4c19952Chris Banes private boolean mEnableDefaultActionBarUp; 69bb994e828a647d6ca3c2480293e7a6e3a4c19952Chris Banes 703954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes ActionBarActivityDelegate(ActionBarActivity activity) { 713954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes mActivity = activity; 723954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes } 733954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 743954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes abstract ActionBar createSupportActionBar(); 753954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 765a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes final ActionBar getSupportActionBar() { 775a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes // The Action Bar should be lazily created as mHasActionBar or mOverlayActionBar 785a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes // could change after onCreate 795a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes if (mHasActionBar || mOverlayActionBar) { 805a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes if (mActionBar == null) { 815a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes mActionBar = createSupportActionBar(); 82bb994e828a647d6ca3c2480293e7a6e3a4c19952Chris Banes 83bb994e828a647d6ca3c2480293e7a6e3a4c19952Chris Banes if (mEnableDefaultActionBarUp) { 84bb994e828a647d6ca3c2480293e7a6e3a4c19952Chris Banes mActionBar.setDisplayHomeAsUpEnabled(true); 85bb994e828a647d6ca3c2480293e7a6e3a4c19952Chris Banes } 865a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes } 875a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes } else { 885a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes // If we're not set to have a Action Bar, null it just in case it's been set 895a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes mActionBar = null; 905a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes } 915a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes return mActionBar; 925a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes } 935a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes 9403527a1c5ca870353671fd8b97a08a989fe62012Chris Banes MenuInflater getMenuInflater() { 955a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes if (mMenuInflater == null) { 96baf2251209e04f0dac4ec7e5d8c0bfc0014c4038Chris Banes ActionBar ab = getSupportActionBar(); 97baf2251209e04f0dac4ec7e5d8c0bfc0014c4038Chris Banes if (ab != null) { 98baf2251209e04f0dac4ec7e5d8c0bfc0014c4038Chris Banes mMenuInflater = new SupportMenuInflater(ab.getThemedContext()); 99baf2251209e04f0dac4ec7e5d8c0bfc0014c4038Chris Banes } else { 100baf2251209e04f0dac4ec7e5d8c0bfc0014c4038Chris Banes mMenuInflater = new SupportMenuInflater(mActivity); 101baf2251209e04f0dac4ec7e5d8c0bfc0014c4038Chris Banes } 1025a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes } 1035a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes return mMenuInflater; 1045a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes } 1055a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes 1065a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes void onCreate(Bundle savedInstanceState) { 1075a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes TypedArray a = mActivity.obtainStyledAttributes(R.styleable.ActionBarWindow); 1085a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes 1095a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes if (!a.hasValue(R.styleable.ActionBarWindow_windowActionBar)) { 1105a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes a.recycle(); 1115a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes throw new IllegalStateException( 1125a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes "You need to use a Theme.AppCompat theme (or descendant) with this activity."); 1135a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes } 1145a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes 1155a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes mHasActionBar = a.getBoolean(R.styleable.ActionBarWindow_windowActionBar, false); 1165a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes mOverlayActionBar = a.getBoolean(R.styleable.ActionBarWindow_windowActionBarOverlay, false); 1175a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes a.recycle(); 118bb994e828a647d6ca3c2480293e7a6e3a4c19952Chris Banes 119bb994e828a647d6ca3c2480293e7a6e3a4c19952Chris Banes if (NavUtils.getParentActivityName(mActivity) != null) { 120bb994e828a647d6ca3c2480293e7a6e3a4c19952Chris Banes if (mActionBar == null) { 121bb994e828a647d6ca3c2480293e7a6e3a4c19952Chris Banes mEnableDefaultActionBarUp = true; 122bb994e828a647d6ca3c2480293e7a6e3a4c19952Chris Banes } else { 123bb994e828a647d6ca3c2480293e7a6e3a4c19952Chris Banes mActionBar.setDisplayHomeAsUpEnabled(true); 124bb994e828a647d6ca3c2480293e7a6e3a4c19952Chris Banes } 125bb994e828a647d6ca3c2480293e7a6e3a4c19952Chris Banes } 1265a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes } 1273954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 1283954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes abstract void onConfigurationChanged(Configuration newConfig); 1293954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 130a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes abstract void onStop(); 131a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes 132a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes abstract void onPostResume(); 133a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes 1343954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes abstract void setContentView(View v); 1353954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 1363954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes abstract void setContentView(int resId); 1373954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 1383954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes abstract void setContentView(View v, ViewGroup.LayoutParams lp); 1393954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 1403954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes abstract void addContentView(View v, ViewGroup.LayoutParams lp); 1413954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 142904507029cd8ea2d070b6df0911b2dd36b7075a6Chris Banes abstract void onTitleChanged(CharSequence title); 1433954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 1443954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes abstract void supportInvalidateOptionsMenu(); 1453954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 146ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes abstract boolean supportRequestWindowFeature(int featureId); 147ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes 1483954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes // Methods used to create and respond to options menu 1493954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes abstract View onCreatePanelView(int featureId); 1503954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 15130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell abstract boolean onPreparePanel(int featureId, View view, Menu menu); 1523954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 1532bc5191a8cc331b404724759a015949a4b5499fbChris Banes boolean onPrepareOptionsPanel(View view, Menu menu) { 1542bc5191a8cc331b404724759a015949a4b5499fbChris Banes if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { 1552bc5191a8cc331b404724759a015949a4b5499fbChris Banes // Call straight through to onPrepareOptionsMenu, bypassing super.onPreparePanel(). 1562bc5191a8cc331b404724759a015949a4b5499fbChris Banes // This is because Activity.onPreparePanel() on <v4.1 calls menu.hasVisibleItems(), 1572bc5191a8cc331b404724759a015949a4b5499fbChris Banes // which interferes with the initially invisible items. 1582bc5191a8cc331b404724759a015949a4b5499fbChris Banes return mActivity.onPrepareOptionsMenu(menu); 1592bc5191a8cc331b404724759a015949a4b5499fbChris Banes } 1602bc5191a8cc331b404724759a015949a4b5499fbChris Banes return mActivity.superOnPrepareOptionsPanel(view, menu); 1612bc5191a8cc331b404724759a015949a4b5499fbChris Banes } 1622bc5191a8cc331b404724759a015949a4b5499fbChris Banes 16330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell abstract boolean onCreatePanelMenu(int featureId, Menu menu); 1643954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 16530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell abstract boolean onMenuItemSelected(int featureId, MenuItem item); 1663954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 167d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes abstract boolean onBackPressed(); 168d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 169d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes abstract ActionMode startSupportActionMode(ActionMode.Callback callback); 170d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 17130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell abstract void setSupportProgressBarVisibility(boolean visible); 172ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes 173ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes abstract void setSupportProgressBarIndeterminateVisibility(boolean visible); 174ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes 175ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes abstract void setSupportProgressBarIndeterminate(boolean indeterminate); 176ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes 177ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes abstract void setSupportProgress(int progress); 178ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes 17945d973fcc4c43f5ea00cddd3d9b947d9e8d8fc4eChris Banes abstract ActionBarDrawerToggle.Delegate getDrawerToggleDelegate(); 18045d973fcc4c43f5ea00cddd3d9b947d9e8d8fc4eChris Banes 181d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes abstract void onContentChanged(); 182d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes 1833954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes protected final String getUiOptionsFromMetadata() { 1843954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes try { 1853954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes PackageManager pm = mActivity.getPackageManager(); 1863954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes ActivityInfo info = pm.getActivityInfo(mActivity.getComponentName(), 1873954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes PackageManager.GET_META_DATA); 1883954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 1893954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes String uiOptions = null; 1903954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes if (info.metaData != null) { 1913954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes uiOptions = info.metaData.getString(METADATA_UI_OPTIONS); 1923954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes } 1933954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes return uiOptions; 1943954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes } catch (PackageManager.NameNotFoundException e) { 1953954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes Log.e(TAG, "getUiOptionsFromMetadata: Activity '" + mActivity.getClass() 1963954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes .getSimpleName() + "' not in manifest"); 1973954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes return null; 1983954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes } 1993954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes } 2003954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 201d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes protected final Context getActionBarThemedContext() { 202d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes Context context = mActivity; 203d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 204d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes // If we have an action bar, initialize the menu with a context themed from it. 2055a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes ActionBar ab = getSupportActionBar(); 206d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes if (ab != null) { 207d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes context = ab.getThemedContext(); 208d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 209d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes return context; 210d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 2113954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes} 212