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