/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.support.v7.app;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v7.appcompat.R;
import android.support.v7.internal.app.WindowCallback;
import android.support.v7.internal.view.SupportMenuInflater;
import android.support.v7.internal.widget.TintTypedArray;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.Toolbar;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
abstract class ActionBarActivityDelegate {
static final String METADATA_UI_OPTIONS = "android.support.UI_OPTIONS";
private static final String TAG = "ActionBarActivityDelegate";
static ActionBarActivityDelegate createDelegate(ActionBarActivity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
return new ActionBarActivityDelegateHC(activity);
} else {
return new ActionBarActivityDelegateBase(activity);
}
}
final ActionBarActivity mActivity;
private ActionBar mActionBar;
private MenuInflater mMenuInflater;
// true if this activity has an action bar.
boolean mHasActionBar;
// true if this activity's action bar overlays other activity content.
boolean mOverlayActionBar;
// true if this any action modes should overlay the activity content
boolean mOverlayActionMode;
// true if this activity is floating (e.g. Dialog)
boolean mIsFloating;
// The default window callback
final WindowCallback mDefaultWindowCallback = new WindowCallback() {
@Override
public boolean onMenuItemSelected(int featureId, MenuItem menuItem) {
return mActivity.onMenuItemSelected(featureId, menuItem);
}
@Override
public boolean onCreatePanelMenu(int featureId, Menu menu) {
return mActivity.superOnCreatePanelMenu(featureId, menu);
}
@Override
public boolean onPreparePanel(int featureId, View menuView, Menu menu) {
return mActivity.superOnPreparePanel(featureId, menuView, menu);
}
@Override
public void onPanelClosed(int featureId, Menu menu) {
mActivity.onPanelClosed(featureId, menu);
}
@Override
public boolean onMenuOpened(int featureId, Menu menu) {
return mActivity.onMenuOpened(featureId, menu);
}
@Override
public ActionMode startActionMode(ActionMode.Callback callback) {
return startSupportActionModeFromWindow(callback);
}
@Override
public View onCreatePanelView(int featureId) {
return mActivity.onCreatePanelView(featureId);
}
};
// The fake window callback we're currently using
private WindowCallback mWindowCallback;
private boolean mIsDestroyed;
ActionBarActivityDelegate(ActionBarActivity activity) {
mActivity = activity;
mWindowCallback = mDefaultWindowCallback;
}
abstract ActionBar createSupportActionBar();
final ActionBar getSupportActionBar() {
// The Action Bar should be lazily created as hasActionBar
// could change after onCreate
if (mHasActionBar) {
if (mActionBar == null) {
mActionBar = createSupportActionBar();
}
}
return mActionBar;
}
final ActionBar peekSupportActionBar() {
return mActionBar;
}
protected final void setSupportActionBar(ActionBar actionBar) {
mActionBar = actionBar;
}
abstract void setSupportActionBar(Toolbar toolbar);
MenuInflater getMenuInflater() {
if (mMenuInflater == null) {
mMenuInflater = new SupportMenuInflater(getActionBarThemedContext());
}
return mMenuInflater;
}
void onCreate(Bundle savedInstanceState) {
TypedArray a = mActivity.obtainStyledAttributes(R.styleable.Theme);
if (!a.hasValue(R.styleable.Theme_windowActionBar)) {
a.recycle();
throw new IllegalStateException(
"You need to use a Theme.AppCompat theme (or descendant) with this activity.");
}
if (a.getBoolean(R.styleable.Theme_windowActionBar, false)) {
mHasActionBar = true;
}
if (a.getBoolean(R.styleable.Theme_windowActionBarOverlay, false)) {
mOverlayActionBar = true;
}
if (a.getBoolean(R.styleable.Theme_windowActionModeOverlay, false)) {
mOverlayActionMode = true;
}
mIsFloating = a.getBoolean(R.styleable.Theme_android_windowIsFloating, false);
a.recycle();
}
abstract void onPostCreate(Bundle savedInstanceState);
abstract void onConfigurationChanged(Configuration newConfig);
abstract void onStop();
abstract void onPostResume();
abstract void setContentView(View v);
abstract void setContentView(int resId);
abstract void setContentView(View v, ViewGroup.LayoutParams lp);
abstract void addContentView(View v, ViewGroup.LayoutParams lp);
abstract void onTitleChanged(CharSequence title);
abstract void supportInvalidateOptionsMenu();
abstract boolean supportRequestWindowFeature(int featureId);
// Methods used to create and respond to options menu
abstract boolean onPreparePanel(int featureId, View view, Menu menu);
abstract void onPanelClosed(int featureId, Menu menu);
abstract boolean onMenuOpened(int featureId, Menu menu);
boolean onPrepareOptionsPanel(View view, Menu menu) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
// Call straight through to onPrepareOptionsMenu, bypassing super.onPreparePanel().
// This is because Activity.onPreparePanel() on <v4.1 calls menu.hasVisibleItems(),
// which interferes with the initially invisible items.
return mActivity.onPrepareOptionsMenu(menu);
}
return mActivity.superOnPrepareOptionsPanel(view, menu);
}
abstract boolean onCreatePanelMenu(int featureId, Menu menu);
abstract boolean onBackPressed();
abstract ActionMode startSupportActionMode(ActionMode.Callback callback);
abstract void setSupportProgressBarVisibility(boolean visible);
abstract void setSupportProgressBarIndeterminateVisibility(boolean visible);
abstract void setSupportProgressBarIndeterminate(boolean indeterminate);
abstract void setSupportProgress(int progress);
abstract boolean dispatchKeyEvent(KeyEvent event);
abstract boolean onKeyShortcut(int keyCode, KeyEvent event);
final ActionBarDrawerToggle.Delegate getDrawerToggleDelegate() {
return new ActionBarDrawableToggleImpl();
}
final android.support.v7.app.ActionBarDrawerToggle.Delegate getV7DrawerToggleDelegate() {
return new ActionBarDrawableToggleImpl();
}
abstract int getHomeAsUpIndicatorAttrId();
abstract void onContentChanged();
final String getUiOptionsFromMetadata() {
try {
PackageManager pm = mActivity.getPackageManager();
ActivityInfo info = pm.getActivityInfo(mActivity.getComponentName(),
PackageManager.GET_META_DATA);
String uiOptions = null;
if (info.metaData != null) {
uiOptions = info.metaData.getString(METADATA_UI_OPTIONS);
}
return uiOptions;
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "getUiOptionsFromMetadata: Activity '" + mActivity.getClass()
.getSimpleName() + "' not in manifest");
return null;
}
}
protected final Context getActionBarThemedContext() {
Context context = null;
// If we have an action bar, let it return a themed context
ActionBar ab = getSupportActionBar();
if (ab != null) {
context = ab.getThemedContext();
}
if (context == null) {
context = mActivity;
}
return context;
}
abstract View createView(String name, @NonNull Context context, @NonNull AttributeSet attrs);
private class ActionBarDrawableToggleImpl implements
android.support.v7.app.ActionBarDrawerToggle.Delegate,
ActionBarDrawerToggle.Delegate {
@Override
public Drawable getThemeUpIndicator() {
final TintTypedArray a = TintTypedArray.obtainStyledAttributes(
getActionBarThemedContext(), null, new int[]{ getHomeAsUpIndicatorAttrId() });
final Drawable result = a.getDrawable(0);
a.recycle();
return result;
}
@Override
public Context getActionBarThemedContext() {
return ActionBarActivityDelegate.this.getActionBarThemedContext();
}
@Override
public boolean isNavigationVisible() {
final ActionBar ab = getSupportActionBar();
return ab != null && (ab.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP) != 0;
}
@Override
public void setActionBarUpIndicator(Drawable upDrawable, int contentDescRes) {
ActionBar ab = getSupportActionBar();
if (ab != null) {
ab.setHomeAsUpIndicator(upDrawable);
ab.setHomeActionContentDescription(contentDescRes);
}
}
@Override
public void setActionBarDescription(int contentDescRes) {
ActionBar ab = getSupportActionBar();
if (ab != null) {
ab.setHomeActionContentDescription(contentDescRes);
}
}
}
abstract ActionMode startSupportActionModeFromWindow(ActionMode.Callback callback);
final void setWindowCallback(WindowCallback callback) {
if (callback == null) {
throw new IllegalArgumentException("callback can not be null");
}
mWindowCallback = callback;
}
final WindowCallback getWindowCallback() {
return mWindowCallback;
}
final void destroy() {
mIsDestroyed = true;
}
final boolean isDestroyed() {
return mIsDestroyed;
}
}
|