diff options
| author | 2010-06-23 20:24:52 -0700 | |
|---|---|---|
| committer | 2010-06-29 14:04:58 -0700 | |
| commit | 89e0645b4157961e8c465eb9c819f965fdb453d8 (patch) | |
| tree | eb174c070624026930067c8472f5425cfc4034ab | |
| parent | 6443de56f3bb9609698b41fc5de04559de039f63 (diff) | |
Added context modes to ActionBar API.
Change-Id: I7c3e782cbf01be7bc671b377fb4d706040888833
19 files changed, 928 insertions, 283 deletions
diff --git a/api/current.xml b/api/current.xml index 0f774f2822be..72630eb14deb 100644 --- a/api/current.xml +++ b/api/current.xml @@ -2088,6 +2088,28 @@ visibility="public" > </field> +<field name="actionBarCloseContextDrawable" + type="int" + transient="false" + volatile="false" + value="16843550" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="actionBarContextBackground" + type="int" + transient="false" + volatile="false" + value="16843549" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="actionButtonPadding" type="int" transient="false" @@ -19435,6 +19457,17 @@ visibility="public" > </constructor> +<method name="finishContextMode" + return="void" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="getCustomNavigationView" return="android.view.View" abstract="true" @@ -19503,19 +19536,6 @@ <parameter name="d" type="android.graphics.drawable.Drawable"> </parameter> </method> -<method name="setCallback" - return="void" - abstract="true" - native="false" - synchronized="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -<parameter name="callback" type="android.app.ActionBar.Callback"> -</parameter> -</method> <method name="setCustomNavigationMode" return="void" abstract="true" @@ -19569,6 +19589,8 @@ > <parameter name="adapter" type="android.widget.SpinnerAdapter"> </parameter> +<parameter name="callback" type="android.app.ActionBar.NavigationCallback"> +</parameter> </method> <method name="setStandardNavigationMode" return="void" @@ -19598,6 +19620,19 @@ <parameter name="title" type="java.lang.CharSequence"> </parameter> </method> +<method name="startContextMode" + return="void" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="callback" type="android.app.ActionBar.ContextModeCallback"> +</parameter> +</method> <field name="DISPLAY_HIDE_HOME" type="int" transient="false" @@ -19665,15 +19700,24 @@ > </field> </class> -<interface name="ActionBar.Callback" +<class name="ActionBar.ContextMode" + extends="java.lang.Object" abstract="true" static="true" final="false" deprecated="not deprecated" visibility="public" > -<method name="onContextItemClicked" - return="boolean" +<constructor name="ActionBar.ContextMode" + type="android.app.ActionBar.ContextMode" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</constructor> +<method name="finish" + return="void" abstract="true" native="false" synchronized="false" @@ -19682,13 +19726,9 @@ deprecated="not deprecated" visibility="public" > -<parameter name="modeId" type="int"> -</parameter> -<parameter name="item" type="android.view.MenuItem"> -</parameter> </method> -<method name="onCreateContextMode" - return="boolean" +<method name="getMenu" + return="android.view.Menu" abstract="true" native="false" synchronized="false" @@ -19697,13 +19737,9 @@ deprecated="not deprecated" visibility="public" > -<parameter name="modeId" type="int"> -</parameter> -<parameter name="menu" type="android.view.Menu"> -</parameter> </method> -<method name="onNavigationItemSelected" - return="boolean" +<method name="invalidate" + return="void" abstract="true" native="false" synchronized="false" @@ -19712,13 +19748,9 @@ deprecated="not deprecated" visibility="public" > -<parameter name="itemPosition" type="int"> -</parameter> -<parameter name="itemId" type="long"> -</parameter> </method> -<method name="onPrepareContextMode" - return="boolean" +<method name="setCustomView" + return="void" abstract="true" native="false" synchronized="false" @@ -19727,33 +19759,46 @@ deprecated="not deprecated" visibility="public" > -<parameter name="modeId" type="int"> -</parameter> -<parameter name="menu" type="android.view.Menu"> +<parameter name="view" type="android.view.View"> </parameter> </method> -</interface> -<class name="ActionBar.SimpleCallback" - extends="java.lang.Object" - abstract="false" - static="true" +<method name="setSubtitle" + return="void" + abstract="true" + native="false" + synchronized="false" + static="false" final="false" deprecated="not deprecated" visibility="public" > -<implements name="android.app.ActionBar.Callback"> -</implements> -<constructor name="ActionBar.SimpleCallback" - type="android.app.ActionBar.SimpleCallback" +<parameter name="subtitle" type="java.lang.CharSequence"> +</parameter> +</method> +<method name="setTitle" + return="void" + abstract="true" + native="false" + synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > -</constructor> +<parameter name="title" type="java.lang.CharSequence"> +</parameter> +</method> +</class> +<interface name="ActionBar.ContextModeCallback" + abstract="true" + static="true" + final="false" + deprecated="not deprecated" + visibility="public" +> <method name="onContextItemClicked" return="boolean" - abstract="false" + abstract="true" native="false" synchronized="false" static="false" @@ -19761,14 +19806,14 @@ deprecated="not deprecated" visibility="public" > -<parameter name="modeId" type="int"> +<parameter name="mode" type="android.app.ActionBar.ContextMode"> </parameter> <parameter name="item" type="android.view.MenuItem"> </parameter> </method> <method name="onCreateContextMode" return="boolean" - abstract="false" + abstract="true" native="false" synchronized="false" static="false" @@ -19776,14 +19821,14 @@ deprecated="not deprecated" visibility="public" > -<parameter name="modeId" type="int"> +<parameter name="mode" type="android.app.ActionBar.ContextMode"> </parameter> <parameter name="menu" type="android.view.Menu"> </parameter> </method> -<method name="onNavigationItemSelected" - return="boolean" - abstract="false" +<method name="onDestroyContextMode" + return="void" + abstract="true" native="false" synchronized="false" static="false" @@ -19791,14 +19836,12 @@ deprecated="not deprecated" visibility="public" > -<parameter name="itemPosition" type="int"> -</parameter> -<parameter name="itemId" type="long"> +<parameter name="mode" type="android.app.ActionBar.ContextMode"> </parameter> </method> <method name="onPrepareContextMode" return="boolean" - abstract="false" + abstract="true" native="false" synchronized="false" static="false" @@ -19806,12 +19849,35 @@ deprecated="not deprecated" visibility="public" > -<parameter name="modeId" type="int"> +<parameter name="mode" type="android.app.ActionBar.ContextMode"> </parameter> <parameter name="menu" type="android.view.Menu"> </parameter> </method> -</class> +</interface> +<interface name="ActionBar.NavigationCallback" + abstract="true" + static="true" + final="false" + deprecated="not deprecated" + visibility="public" +> +<method name="onNavigationItemSelected" + return="boolean" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="itemPosition" type="int"> +</parameter> +<parameter name="itemId" type="long"> +</parameter> +</method> +</interface> <class name="Activity" extends="android.view.ContextThemeWrapper" abstract="false" @@ -180005,6 +180071,19 @@ <parameter name="alphaChar" type="char"> </parameter> </method> +<method name="setShowAsAction" + return="void" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="actionEnum" type="int"> +</parameter> +</method> <method name="setTitle" return="android.view.MenuItem" abstract="true" @@ -180057,6 +180136,39 @@ <parameter name="visible" type="boolean"> </parameter> </method> +<field name="SHOW_AS_ACTION_ALWAYS" + type="int" + transient="false" + volatile="false" + value="2" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SHOW_AS_ACTION_IF_ROOM" + type="int" + transient="false" + volatile="false" + value="1" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SHOW_AS_ACTION_NEVER" + type="int" + transient="false" + volatile="false" + value="0" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> </interface> <interface name="MenuItem.OnMenuItemClickListener" abstract="true" diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java index 4387361da041..1775a0daa2eb 100644 --- a/core/java/android/app/ActionBar.java +++ b/core/java/android/app/ActionBar.java @@ -66,14 +66,7 @@ public abstract class ActionBar { * navigation elements. This includes logo and icon. */ public static final int DISPLAY_HIDE_HOME = 0x2; - - /** - * Set the callback that the ActionBar will use to handle events - * and populate menus. - * @param callback Callback to use - */ - public abstract void setCallback(Callback callback); - + /** * Set the action bar into custom navigation mode, supplying a view * for custom navigation. @@ -95,8 +88,11 @@ public abstract class ActionBar { * @param adapter An adapter that will provide views both to display * the current navigation selection and populate views * within the dropdown navigation menu. + * @param callback A NavigationCallback that will receive events when the user + * selects a navigation item. */ - public abstract void setDropdownNavigationMode(SpinnerAdapter adapter); + public abstract void setDropdownNavigationMode(SpinnerAdapter adapter, + NavigationCallback callback); /** * Set the action bar into standard navigation mode, supplying a title and subtitle. @@ -198,48 +194,136 @@ public abstract class ActionBar { */ public abstract int getDisplayOptions(); + public abstract void startContextMode(ContextModeCallback callback); + public abstract void finishContextMode(); + /** - * Callback interface for ActionBar events. + * Represents a contextual mode of the Action Bar. Context modes can be used for + * modal interactions with activity content and replace the normal Action Bar until finished. + * Examples of good contextual modes include selection modes, search, content editing, etc. */ - public interface Callback { + public static abstract class ContextMode { /** - * This method is called whenever a navigation item in your action bar - * is selected. - * - * @param itemPosition Position of the item clicked. - * @param itemId ID of the item clicked. - * @return True if the event was handled, false otherwise. + * Set the title of the context mode. This method will have no visible effect if + * a custom view has been set. + * + * @param title Title string to set + * + * @see #setCustomView(View) */ - public boolean onNavigationItemSelected(int itemPosition, long itemId); + public abstract void setTitle(CharSequence title); - /* - * In progress + /** + * Set the subtitle of the context mode. This method will have no visible effect if + * a custom view has been set. + * + * @param subtitle Subtitle string to set + * + * @see #setCustomView(View) */ - public boolean onCreateContextMode(int modeId, Menu menu); - public boolean onPrepareContextMode(int modeId, Menu menu); - public boolean onContextItemClicked(int modeId, MenuItem item); + public abstract void setSubtitle(CharSequence subtitle); + + /** + * Set a custom view for this context mode. The custom view will take the place of + * the title and subtitle. Useful for things like search boxes. + * + * @param view Custom view to use in place of the title/subtitle. + * + * @see #setTitle(CharSequence) + * @see #setSubtitle(CharSequence) + */ + public abstract void setCustomView(View view); + + /** + * Invalidate the context mode and refresh menu content. The context mode's + * {@link ContextModeCallback} will have its + * {@link ContextModeCallback#onPrepareContextMode(ContextMode, Menu)} method called. + * If it returns true the menu will be scanned for updated content and any relevant changes + * will be reflected to the user. + */ + public abstract void invalidate(); + + /** + * Finish and close this context mode. The context mode's {@link ContextModeCallback} will + * have its {@link ContextModeCallback#onDestroyContextMode(ContextMode)} method called. + */ + public abstract void finish(); + + /** + * Returns the menu of actions that this context mode presents. + * @return The context mode's menu. + */ + public abstract Menu getMenu(); } /** - * Simple stub implementations of ActionBar.Callback methods. - * Extend this if you only need a subset of Callback functionality. + * Callback interface for ActionBar context modes. Supplied to + * {@link ActionBar#startContextMode(ContextModeCallback)}, a ContextModeCallback + * configures and handles events raised by a user's interaction with a context mode. + * + * <p>A context mode's lifecycle is as follows: + * <ul> + * <li>{@link ContextModeCallback#onCreateContextMode(ContextMode, Menu)} once on initial + * creation</li> + * <li>{@link ContextModeCallback#onPrepareContextMode(ContextMode, Menu)} after creation + * and any time the {@link ContextMode} is invalidated</li> + * <li>{@link ContextModeCallback#onContextItemClicked(ContextMode, MenuItem)} any time a + * contextual action button is clicked</li> + * <li>{@link ContextModeCallback#onDestroyContextMode(ContextMode)} when the context mode + * is closed</li> + * </ul> */ - public static class SimpleCallback implements Callback { - public boolean onCreateContextMode(int modeId, Menu menu) { - return false; - } + public interface ContextModeCallback { + /** + * Called when a context mode is first created. The menu supplied will be used to generate + * action buttons for the context mode. + * + * @param mode ContextMode being created + * @param menu Menu used to populate contextual action buttons + * @return true if the context mode should be created, false if entering this context mode + * should be aborted. + */ + public boolean onCreateContextMode(ContextMode mode, Menu menu); - public boolean onPrepareContextMode(int modeId, Menu menu) { - return false; - } + /** + * Called to refresh a context mode's action menu whenever it is invalidated. + * + * @param mode ContextMode being prepared + * @param menu Menu used to populate contextual action buttons + * @return true if the menu or context mode was updated, false otherwise. + */ + public boolean onPrepareContextMode(ContextMode mode, Menu menu); - public boolean onContextItemClicked(int modeId, MenuItem item) { - return false; - } - - public boolean onNavigationItemSelected(int itemPosition, long itemId) { - return false; - } + /** + * Called to report a user click on a contextual action button. + * + * @param mode The current ContextMode + * @param item The item that was clicked + * @return true if this callback handled the event, false if the standard MenuItem + * invocation should continue. + */ + public boolean onContextItemClicked(ContextMode mode, MenuItem item); + + /** + * Called when a context mode is about to be exited and destroyed. + * + * @param mode The current ContextMode being destroyed + */ + public void onDestroyContextMode(ContextMode mode); + } + + /** + * Callback interface for ActionBar navigation events. + */ + public interface NavigationCallback { + /** + * This method is called whenever a navigation item in your action bar + * is selected. + * + * @param itemPosition Position of the item clicked. + * @param itemId ID of the item clicked. + * @return True if the event was handled, false otherwise. + */ + public boolean onNavigationItemSelected(int itemPosition, long itemId); } - } diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 91ff0a524d32..8825b8cc7587 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -52,7 +52,6 @@ import android.util.Config; import android.util.EventLog; import android.util.Log; import android.util.SparseArray; -import android.view.ActionBarView; import android.view.ContextMenu; import android.view.ContextThemeWrapper; import android.view.InflateException; @@ -74,8 +73,9 @@ import android.view.accessibility.AccessibilityEvent; import android.widget.AdapterView; import android.widget.LinearLayout; -import com.android.internal.app.SplitActionBar; +import com.android.internal.app.ActionBarImpl; import com.android.internal.policy.PolicyManager; +import com.android.internal.widget.ActionBarView; /** * An activity is a single, focused thing that the user can do. Almost all @@ -1675,20 +1675,12 @@ public class Activity extends ContextThemeWrapper * initializes the ActionBar with the view, and sets mActionBar. */ private void initActionBar() { - if (!getWindow().hasFeature(Window.FEATURE_ACTION_BAR)) { + Window window = getWindow(); + if (!window.hasFeature(Window.FEATURE_ACTION_BAR)) { return; } - ActionBarView view = (ActionBarView) findViewById(com.android.internal.R.id.action_bar); - if (view != null) { - LinearLayout splitView = - (LinearLayout) findViewById(com.android.internal.R.id.context_action_bar); - if (splitView != null) { - mActionBar = new SplitActionBar(view, splitView); - } - } else { - Log.e(TAG, "Could not create action bar; view not found in window decor."); - } + mActionBar = new ActionBarImpl(getWindow().getDecorView()); } /** diff --git a/core/java/android/view/MenuInflater.java b/core/java/android/view/MenuInflater.java index 3335e85436c8..4a966b5d77c0 100644 --- a/core/java/android/view/MenuInflater.java +++ b/core/java/android/view/MenuInflater.java @@ -242,12 +242,12 @@ public class MenuInflater { private boolean itemEnabled; /** - * Sync to attrs.xml enum: + * Sync to attrs.xml enum, values in MenuItem: * - 0: never * - 1: ifRoom * - 2: always */ - private int itemShowAsAction; + private int itemShowAsAction = MenuItem.SHOW_AS_ACTION_NEVER; private String itemListenerMethodName; @@ -346,7 +346,8 @@ public class MenuInflater { .setTitleCondensed(itemTitleCondensed) .setIcon(itemIconResId) .setAlphabeticShortcut(itemAlphabeticShortcut) - .setNumericShortcut(itemNumericShortcut); + .setNumericShortcut(itemNumericShortcut) + .setShowAsAction(itemShowAsAction); if (itemListenerMethodName != null) { item.setOnMenuItemClickListener( @@ -358,7 +359,6 @@ public class MenuInflater { if (itemCheckable >= 2) { impl.setExclusiveCheckable(true); } - impl.setShowAsAction(itemShowAsAction); } } diff --git a/core/java/android/view/MenuItem.java b/core/java/android/view/MenuItem.java index fcebec5d8766..bfa349c7bf0b 100644 --- a/core/java/android/view/MenuItem.java +++ b/core/java/android/view/MenuItem.java @@ -31,6 +31,21 @@ import android.view.View.OnCreateContextMenuListener; * For a feature set of specific menu types, see {@link Menu}. */ public interface MenuItem { + /* + * These should be kept in sync with attrs.xml enum constants for showAsAction + */ + /** Never show this item as a button in an Action Bar. */ + public static final int SHOW_AS_ACTION_NEVER = 0; + /** Show this item as a button in an Action Bar if the system decides there is room for it. */ + public static final int SHOW_AS_ACTION_IF_ROOM = 1; + /** + * Always show this item as a button in an Action Bar. + * Use sparingly! If too many items are set to always show in the Action Bar it can + * crowd the Action Bar and degrade the user experience on devices with smaller screens. + * A good rule of thumb is to have no more than 2 items set to always show at a time. + */ + public static final int SHOW_AS_ACTION_ALWAYS = 2; + /** * Interface definition for a callback to be invoked when a menu item is * clicked. @@ -381,4 +396,13 @@ public interface MenuItem { * menu item to the menu. This can be null. */ public ContextMenuInfo getMenuInfo(); + + /** + * Sets how this item should display in the presence of an Action Bar. + * + * @param actionEnum How the item should display. One of + * + * @see android.app.ActionBar + */ + public void setShowAsAction(int actionEnum); }
\ No newline at end of file diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java new file mode 100644 index 000000000000..b36524e2d676 --- /dev/null +++ b/core/java/com/android/internal/app/ActionBarImpl.java @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2010 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 com.android.internal.app; + +import com.android.internal.view.menu.ActionMenu; +import com.android.internal.view.menu.ActionMenuItem; +import com.android.internal.widget.ActionBarContextView; +import com.android.internal.widget.ActionBarView; + +import android.app.ActionBar; +import android.graphics.drawable.Drawable; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.SpinnerAdapter; +import android.widget.ViewAnimator; + +/** + * ActionBarImpl is the ActionBar implementation used + * by devices of all screen sizes. If it detects a compatible decor, + * it will split contextual modes across both the ActionBarView at + * the top of the screen and a horizontal LinearLayout at the bottom + * which is normally hidden. + */ +public class ActionBarImpl extends ActionBar { + private static final int NORMAL_VIEW = 0; + private static final int CONTEXT_VIEW = 1; + + private ViewAnimator mAnimatorView; + private ActionBarView mActionView; + private ActionBarContextView mUpperContextView; + private LinearLayout mLowerContextView; + + private ContextMode mContextMode; + + private static final int CONTEXT_DISPLAY_NORMAL = 0; + private static final int CONTEXT_DISPLAY_SPLIT = 1; + + private int mContextDisplayMode; + + public ActionBarImpl(View decor) { + mActionView = (ActionBarView) decor.findViewById(com.android.internal.R.id.action_bar); + mUpperContextView = (ActionBarContextView) decor.findViewById( + com.android.internal.R.id.action_context_bar); + mLowerContextView = (LinearLayout) decor.findViewById( + com.android.internal.R.id.lower_action_context_bar); + mAnimatorView = (ViewAnimator) decor.findViewById( + com.android.internal.R.id.action_bar_animator); + + if (mActionView == null || mUpperContextView == null || mAnimatorView == null) { + throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + + "with a compatible window decor layout"); + } + + mContextDisplayMode = mLowerContextView == null ? + CONTEXT_DISPLAY_NORMAL : CONTEXT_DISPLAY_SPLIT; + } + + public void setCustomNavigationMode(View view) { + mActionView.setCustomNavigationView(view); + mActionView.setCallback(null); + } + + public void setDropdownNavigationMode(SpinnerAdapter adapter, NavigationCallback callback) { + mActionView.setCallback(callback); + mActionView.setNavigationMode(NAVIGATION_MODE_DROPDOWN_LIST); + mActionView.setDropdownAdapter(adapter); + } + + public void setStandardNavigationMode(CharSequence title) { + setStandardNavigationMode(title, null); + } + + public void setStandardNavigationMode(CharSequence title, CharSequence subtitle) { + mActionView.setNavigationMode(NAVIGATION_MODE_STANDARD); + mActionView.setTitle(title); + mActionView.setSubtitle(subtitle); + mActionView.setCallback(null); + } + + public void setDisplayOptions(int options) { + mActionView.setDisplayOptions(options); + } + + public void setDisplayOptions(int options, int mask) { + final int current = mActionView.getDisplayOptions(); + mActionView.setDisplayOptions((options & mask) | (current & ~mask)); + } + + public void setBackgroundDrawable(Drawable d) { + mActionView.setBackgroundDrawable(d); + } + + public View getCustomNavigationView() { + return mActionView.getCustomNavigationView(); + } + + public CharSequence getTitle() { + return mActionView.getTitle(); + } + + public CharSequence getSubtitle() { + return mActionView.getSubtitle(); + } + + public int getNavigationMode() { + return mActionView.getNavigationMode(); + } + + public int getDisplayOptions() { + return mActionView.getDisplayOptions(); + } + + @Override + public void startContextMode(ContextModeCallback callback) { + if (mContextMode != null) { + mContextMode.finish(); + } + mContextMode = new ContextMode(callback); + if (callback.onCreateContextMode(mContextMode, mContextMode.getMenu())) { + mContextMode.invalidate(); + mUpperContextView.initForMode(mContextMode); + mAnimatorView.setDisplayedChild(CONTEXT_VIEW); + if (mLowerContextView != null) { + // TODO animate this + mLowerContextView.setVisibility(View.VISIBLE); + } + } + } + + @Override + public void finishContextMode() { + if (mContextMode != null) { + mContextMode.finish(); + } + } + + /** + * @hide + */ + public class ContextMode extends ActionBar.ContextMode { + private ContextModeCallback mCallback; + private ActionMenu mMenu; + + public ContextMode(ContextModeCallback callback) { + mCallback = callback; + mMenu = new ActionMenu(mActionView.getContext()); + } + + @Override + public Menu getMenu() { + return mMenu; + } + + @Override + public void finish() { + mCallback.onDestroyContextMode(this); + mUpperContextView.closeMode(); + if (mLowerContextView != null) { + mLowerContextView.removeAllViews(); + } + mAnimatorView.setDisplayedChild(NORMAL_VIEW); + if (mLowerContextView != null && mLowerContextView.getVisibility() != View.GONE) { + // TODO Animate this + mLowerContextView.setVisibility(View.GONE); + } + mContextMode = null; + } + + @Override + public void invalidate() { + if (mCallback.onPrepareContextMode(this, mMenu)) { + // Refresh content in both context views + } + } + + @Override + public void setCustomView(View view) { + mUpperContextView.setCustomView(view); + } + + @Override + public void setSubtitle(CharSequence subtitle) { + mUpperContextView.setSubtitle(subtitle); + } + + @Override + public void setTitle(CharSequence title) { + mUpperContextView.setTitle(title); + } + + public void dispatchOnContextItemClicked(MenuItem item) { + ActionMenuItem actionItem = (ActionMenuItem) item; + if (!actionItem.invoke()) { + mCallback.onContextItemClicked(this, item); + } + } + } +} diff --git a/core/java/com/android/internal/app/SplitActionBar.java b/core/java/com/android/internal/app/SplitActionBar.java deleted file mode 100644 index 05ae79395930..000000000000 --- a/core/java/com/android/internal/app/SplitActionBar.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2010 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 com.android.internal.app; - -import android.app.ActionBar; -import android.graphics.drawable.Drawable; -import android.view.ActionBarView; -import android.view.View; -import android.widget.LinearLayout; -import android.widget.SpinnerAdapter; - -/** - * SplitActionBar is the ActionBar implementation used - * by small-screen devices. It expects to split contextual - * modes across both the ActionBarView at the top of the screen - * and a horizontal LinearLayout at the bottom which is normally - * hidden. - */ -public class SplitActionBar extends ActionBar { - private ActionBarView mActionView; - private LinearLayout mContextView; - - public SplitActionBar(ActionBarView view, LinearLayout contextView) { - mActionView = view; - mContextView = contextView; - } - - public void setCallback(Callback callback) { - mActionView.setCallback(callback); - } - - public void setCustomNavigationMode(View view) { - mActionView.setCustomNavigationView(view); - } - - public void setDropdownNavigationMode(SpinnerAdapter adapter) { - mActionView.setNavigationMode(NAVIGATION_MODE_DROPDOWN_LIST); - mActionView.setDropdownAdapter(adapter); - } - - public void setStandardNavigationMode(CharSequence title) { - setStandardNavigationMode(title, null); - } - - public void setStandardNavigationMode(CharSequence title, CharSequence subtitle) { - mActionView.setNavigationMode(NAVIGATION_MODE_STANDARD); - mActionView.setTitle(title); - mActionView.setSubtitle(subtitle); - } - - public void setTitle(CharSequence title) { - mActionView.setTitle(title); - } - - public void setSubtitle(CharSequence subtitle) { - mActionView.setSubtitle(subtitle); - } - - public void setDisplayOptions(int options) { - mActionView.setDisplayOptions(options); - } - - public void setDisplayOptions(int options, int mask) { - final int current = mActionView.getDisplayOptions(); - mActionView.setDisplayOptions((options & mask) | (current & ~mask)); - } - - public void setBackgroundDrawable(Drawable d) { - mActionView.setBackgroundDrawable(d); - } - - public View getCustomNavigationView() { - return mActionView.getCustomNavigationView(); - } - - public CharSequence getTitle() { - return mActionView.getTitle(); - } - - public CharSequence getSubtitle() { - return mActionView.getSubtitle(); - } - - public int getNavigationMode() { - return mActionView.getNavigationMode(); - } - - public int getDisplayOptions() { - return mActionView.getDisplayOptions(); - } -} diff --git a/core/java/com/android/internal/view/menu/ActionMenuItem.java b/core/java/com/android/internal/view/menu/ActionMenuItem.java index 47d5fb97737b..035875ac0bf4 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuItem.java +++ b/core/java/com/android/internal/view/menu/ActionMenuItem.java @@ -218,4 +218,8 @@ public class ActionMenuItem implements MenuItem { return false; } + + public void setShowAsAction(int show) { + // Do nothing. ActionMenuItems always show as action buttons. + } } diff --git a/core/java/com/android/internal/view/menu/ActionMenuView.java b/core/java/com/android/internal/view/menu/ActionMenuView.java index 97d27ac25da4..c3fe5dcba0c7 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuView.java +++ b/core/java/com/android/internal/view/menu/ActionMenuView.java @@ -53,7 +53,7 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo final Resources res = getResources(); final int size = res.getDimensionPixelSize(com.android.internal.R.dimen.action_icon_size); final int spaceAvailable = res.getDisplayMetrics().widthPixels / 2; - final int itemSpace = size + mItemPadding; + final int itemSpace = size + mItemPadding; mMaxItems = spaceAvailable / (itemSpace > 0 ? itemSpace : 1); } diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java index dc1e81f04b1d..5fe75be927fd 100644 --- a/core/java/com/android/internal/view/menu/MenuItemImpl.java +++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java @@ -75,13 +75,7 @@ public final class MenuItemImpl implements MenuItem { private static final int HIDDEN = 0x00000008; private static final int ENABLED = 0x00000010; private static final int IS_ACTION = 0x00000020; - - /* - * These should be kept in sync with attrs.xml enum constants for showAsAction - */ - private static final int SHOW_AS_ACTION_NEVER = 0; - private static final int SHOW_AS_ACTION_IF_ROOM = 1; - private static final int SHOW_AS_ACTION_ALWAYS = 2; + private int mShowAsAction = SHOW_AS_ACTION_NEVER; /** Used for the icon resource ID if this item does not have an icon */ @@ -659,13 +653,7 @@ public final class MenuItemImpl implements MenuItem { mFlags &= ~IS_ACTION; } } - - /** - * Used by MenuInflater to set how this item should display in the presence of - * an Action Bar. - * - * @param actionEnum Enum flag as defined in attrs.xml/SHOW_AS_ constants. - */ + public void setShowAsAction(int actionEnum) { mShowAsAction = actionEnum; mMenu.onItemActionRequestChanged(this); diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java new file mode 100644 index 000000000000..0ad4447e3cee --- /dev/null +++ b/core/java/com/android/internal/widget/ActionBarContextView.java @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2010 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 com.android.internal.widget; + +import com.android.internal.R; +import com.android.internal.app.ActionBarImpl; + +import android.app.ActionBar; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageButton; +import android.widget.TextView; + +/** + * @hide + */ +public class ActionBarContextView extends ViewGroup { + // TODO: This must be defined in the default theme + private static final int CONTENT_HEIGHT_DIP = 50; + + private int mItemPadding; + private int mItemMargin; + private int mContentHeight; + + private CharSequence mTitle; + private CharSequence mSubtitle; + + private ImageButton mCloseButton; + private View mCustomView; + private TextView mTitleView; + private Drawable mCloseDrawable; + + public ActionBarContextView(Context context) { + this(context, null, 0); + } + + public ActionBarContextView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public ActionBarContextView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + TypedArray a = context.obtainStyledAttributes(attrs, + com.android.internal.R.styleable.Theme); + mItemPadding = a.getDimensionPixelOffset( + com.android.internal.R.styleable.Theme_actionButtonPadding, 0); + setBackgroundDrawable(a.getDrawable( + com.android.internal.R.styleable.Theme_actionBarContextBackground)); + mCloseDrawable = a.getDrawable( + com.android.internal.R.styleable.Theme_actionBarCloseContextDrawable); + mItemMargin = mItemPadding / 2; + + mContentHeight = CONTENT_HEIGHT_DIP; + a.recycle(); + } + + public void setCustomView(View view) { + if (mCustomView != null) { + removeView(mCustomView); + } + mCustomView = view; + if (mTitleView != null) { + removeView(mTitleView); + mTitleView = null; + } + if (view != null) { + addView(view); + } + requestLayout(); + } + + public void setTitle(CharSequence title) { + mTitle = title; + if (mTitleView == null) { + LayoutInflater inflater = LayoutInflater.from(getContext()); + mTitleView = (TextView) inflater.inflate(R.layout.action_bar_title_item, null); + mTitleView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, + LayoutParams.WRAP_CONTENT)); + if (title != null) { + mTitleView.setText(title); + } + addView(mTitleView); + } else { + mTitleView.setText(title); + if (mTitleView.getParent() == null) { + addView(mTitleView); + } + } + } + + public void setSubtitle(CharSequence subtitle) { + mSubtitle = subtitle; + // TODO add subtitle support + } + + public void initForMode(final ActionBar.ContextMode mode) { + final ActionBarImpl.ContextMode implMode = (ActionBarImpl.ContextMode) mode; + + if (mCloseButton == null) { + mCloseButton = new ImageButton(getContext()); + mCloseButton.setImageDrawable(mCloseDrawable); + mCloseButton.setBackgroundDrawable(null); + mCloseButton.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + mode.finish(); + } + }); + } + addView(mCloseButton); + + final Context context = getContext(); + final Menu menu = mode.getMenu(); + final int itemCount = menu.size(); + for (int i = 0; i < itemCount; i++) { + final MenuItem item = menu.getItem(i); + final ImageButton button = new ImageButton(context, null, + com.android.internal.R.attr.actionButtonStyle); + button.setClickable(true); + button.setFocusable(true); + button.setImageDrawable(item.getIcon()); + button.setId(item.getItemId()); + button.setVisibility(item.isVisible() ? VISIBLE : GONE); + button.setEnabled(item.isEnabled()); + + button.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + implMode.dispatchOnContextItemClicked(item); + } + }); + + addView(button); + } + requestLayout(); + } + + public void closeMode() { + removeAllViews(); + mCustomView = null; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final int widthMode = MeasureSpec.getMode(widthMeasureSpec); + if (widthMode != MeasureSpec.EXACTLY) { + throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + + "with android:layout_width=\"match_parent\" (or fill_parent)"); + } + + final int heightMode = MeasureSpec.getMode(heightMeasureSpec); + if (heightMode != MeasureSpec.AT_MOST) { + throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + + "with android:layout_height=\"wrap_content\""); + } + + final int contentWidth = MeasureSpec.getSize(widthMeasureSpec); + final int itemMargin = mItemPadding; + + int availableWidth = contentWidth - getPaddingLeft() - getPaddingRight(); + final int height = mContentHeight - getPaddingTop() - getPaddingBottom(); + final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST); + + if (mCloseButton != null) { + availableWidth = measureChildView(mCloseButton, availableWidth, + childSpecHeight, itemMargin); + } + + if (mTitleView != null && mCustomView == null) { + availableWidth = measureChildView(mTitleView, availableWidth, + childSpecHeight, itemMargin); + } + + final int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + final View child = getChildAt(i); + if (child == mCloseButton || child == mTitleView || child == mCustomView) { + continue; + } + + availableWidth = measureChildView(child, availableWidth, childSpecHeight, itemMargin); + } + + if (mCustomView != null) { + mCustomView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); + } + + setMeasuredDimension(contentWidth, mContentHeight); + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + int x = getPaddingLeft(); + final int y = getPaddingTop(); + final int contentHeight = b - t - getPaddingTop() - getPaddingBottom(); + final int itemMargin = mItemPadding; + + if (mCloseButton != null && mCloseButton.getVisibility() != GONE) { + x += positionChild(mCloseButton, x, y, contentHeight); + } + + if (mTitleView != null && mCustomView == null) { + x += positionChild(mTitleView, x, y, contentHeight) + itemMargin; + } + + if (mCustomView != null) { + x += positionChild(mCustomView, x, y, contentHeight) + itemMargin; + } + + x = r - l - getPaddingRight(); + + final int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + final View child = getChildAt(i); + if (child == mCloseButton || child == mTitleView || child == mCustomView) { + continue; + } + + x -= positionChildInverse(child, x, y, contentHeight) + itemMargin; + } + } + + private int measureChildView(View child, int availableWidth, int childSpecHeight, int spacing) { + child.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), + childSpecHeight); + + availableWidth -= child.getMeasuredWidth(); + availableWidth -= spacing; + + return availableWidth; + } + + private int positionChild(View child, int x, int y, int contentHeight) { + int childWidth = child.getMeasuredWidth(); + int childHeight = child.getMeasuredHeight(); + int childTop = y + (contentHeight - childHeight) / 2; + + child.layout(x, childTop, x + childWidth, childTop + childHeight); + + return childWidth; + } + + private int positionChildInverse(View child, int x, int y, int contentHeight) { + int childWidth = child.getMeasuredWidth(); + int childHeight = child.getMeasuredHeight(); + int childTop = y + (contentHeight - childHeight) / 2; + + child.layout(x - childWidth, childTop, x, childTop + childHeight); + + return childWidth; + } +} diff --git a/core/java/android/view/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java index 5142c50c8ad1..dcc1731b1a6a 100644 --- a/core/java/android/view/ActionBarView.java +++ b/core/java/com/android/internal/widget/ActionBarView.java @@ -14,17 +14,16 @@ * limitations under the License. */ -package android.view; +package com.android.internal.widget; import com.android.internal.R; -import com.android.internal.view.menu.ActionMenu; import com.android.internal.view.menu.ActionMenuItem; import com.android.internal.view.menu.ActionMenuView; import com.android.internal.view.menu.MenuBuilder; import android.app.ActionBar; import android.app.Activity; -import android.app.ActionBar.Callback; +import android.app.ActionBar.NavigationCallback; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; @@ -34,7 +33,10 @@ import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.DisplayMetrics; -import android.util.SparseArray; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.View; +import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ImageView; import android.widget.Spinner; @@ -90,9 +92,7 @@ public class ActionBarView extends ViewGroup { private ActionMenuItem mLogoNavItem; - private SparseArray<ActionMenu> mContextMenus; - - private Callback mCallback; + private NavigationCallback mCallback; private final AdapterView.OnItemSelectedListener mNavItemSelectedListener = new AdapterView.OnItemSelectedListener() { @@ -173,11 +173,9 @@ public class ActionBarView extends ViewGroup { } }; } - - mContextMenus = new SparseArray<ActionMenu>(); } - public void setCallback(Callback callback) { + public void setCallback(NavigationCallback callback) { mCallback = callback; } @@ -310,34 +308,6 @@ public class ActionBarView extends ViewGroup { return mDisplayOptions; } - public void setContextMode(int mode) { - Callback callback = mCallback; - if (callback == null) { - throw new IllegalStateException( - "Attempted to set ActionBar context mode with no callback"); - } - - ActionMenu menu = mContextMenus.get(mode); - if (menu == null) { - // Initialize the new mode - menu = new ActionMenu(getContext()); - - if (!callback.onCreateContextMode(mode, menu)) { - throw new IllegalArgumentException( - "ActionBar callback does not know how to create context mode " + mode); - } - mContextMenus.put(mode, menu); - } - - if (callback.onPrepareContextMode(mode, menu)) { - // TODO Set mode, animate, etc. - } - } - - public void exitContextMode() { - // TODO Turn off context mode; go back to normal. - } - @Override protected void onFinishInflate() { super.onFinishInflate(); diff --git a/core/res/res/drawable/action_bar_context_background.xml b/core/res/res/drawable/action_bar_context_background.xml new file mode 100644 index 000000000000..8789898186ec --- /dev/null +++ b/core/res/res/drawable/action_bar_context_background.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 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. +--> + +<shape xmlns:android="http://schemas.android.com/apk/res/android"> + <gradient + android:startColor="#ff000000" + android:centerColor="#ffd1d2d4" + android:endColor="#ff85878a" + android:angle="270" /> +</shape> diff --git a/core/res/res/layout/screen_action_bar.xml b/core/res/res/layout/screen_action_bar.xml index 01a4b429afe8..f39852b8d314 100644 --- a/core/res/res/layout/screen_action_bar.xml +++ b/core/res/res/layout/screen_action_bar.xml @@ -21,20 +21,30 @@ This is an optimized layout for a screen with the Action Bar enabled. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:fitsSystemWindows="true"> - <ActionBarView android:id="@+id/action_bar" - android:layout_width="match_parent" - android:layout_height="wrap_content" - style="?android:attr/windowActionBarStyle" /> + <ViewAnimator android:id="@+id/action_bar_animator" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:inAnimation="@anim/push_down_in" + android:outAnimation="@anim/push_down_out"> + <com.android.internal.widget.ActionBarView + android:id="@+id/action_bar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + style="?android:attr/windowActionBarStyle" /> + <com.android.internal.widget.ActionBarContextView + android:id="@+id/action_context_bar" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + </ViewAnimator> <FrameLayout android:id="@android:id/content" android:layout_width="match_parent" android:layout_height="0dip" android:layout_weight="1" android:foregroundGravity="fill_horizontal|top" android:foreground="?android:attr/windowContentOverlay" /> - <LinearLayout android:id="@+id/context_action_bar" + <LinearLayout android:id="@+id/lower_action_context_bar" android:layout_width="match_parent" android:layout_height="wrap_content" style="?android:attr/windowActionBarStyle" android:visibility="gone" /> </LinearLayout> - diff --git a/core/res/res/layout/screen_xlarge_action_bar.xml b/core/res/res/layout/screen_xlarge_action_bar.xml new file mode 100644 index 000000000000..c51ca13031b5 --- /dev/null +++ b/core/res/res/layout/screen_xlarge_action_bar.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 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. +--> + +<!-- +This is an optimized layout for a screen with the Action Bar enabled. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:fitsSystemWindows="true"> + <ViewAnimator android:id="@+id/action_bar_animator" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:inAnimation="@anim/push_down_in" + android:outAnimation="@anim/push_down_out"> + <com.android.internal.widget.ActionBarView + android:id="@+id/action_bar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + style="?android:attr/windowActionBarStyle" /> + <com.android.internal.widget.ActionBarContextView + android:id="@+id/action_context_bar" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + </ViewAnimator> + <FrameLayout android:id="@android:id/content" + android:layout_width="match_parent" + android:layout_height="0dip" + android:layout_weight="1" + android:foregroundGravity="fill_horizontal|top" + android:foreground="?android:attr/windowContentOverlay" /> +</LinearLayout> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 7470eca5fb56..b3f280b8919c 100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -444,6 +444,8 @@ <eat-comment /> <!-- Default amount of padding to use between action buttons. --> <attr name="actionButtonPadding" format="dimension" /> + <attr name="actionBarContextBackground" format="reference" /> + <attr name="actionBarCloseContextDrawable" format="reference" /> <!-- =================== --> <!-- Preference styles --> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index e98c8afc9546..b9e5e8400aa1 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1300,6 +1300,8 @@ <public type="attr" name="showAsAction" /> <public type="attr" name="actionButtonPadding" /> <public type="attr" name="previewImage" /> + <public type="attr" name="actionBarContextBackground" /> + <public type="attr" name="actionBarCloseContextDrawable" /> <public type="id" name="home" /> diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index 76bba4b14d32..2dfe9ab3b6f2 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -206,6 +206,8 @@ <!-- Action bar styles --> <item name="actionButtonPadding">12dip</item> + <item name="actionBarContextBackground">@android:drawable/action_bar_context_background</item> + <item name="actionBarCloseContextDrawable">@android:drawable/ic_menu_close_clear_cancel</item> </style> <!-- Variant of the default (dark) theme with no title bar --> diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index e7511e0e1d82..5c56d3c42949 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -29,6 +29,7 @@ import com.android.internal.view.menu.MenuBuilder; import com.android.internal.view.menu.MenuDialogHelper; import com.android.internal.view.menu.MenuView; import com.android.internal.view.menu.SubMenuBuilder; +import com.android.internal.widget.ActionBarView; import android.app.KeyguardManager; import android.app.SearchManager; @@ -53,7 +54,6 @@ import android.util.Config; import android.util.EventLog; import android.util.Log; import android.util.SparseArray; -import android.view.ActionBarView; import android.view.Gravity; import android.view.HapticFeedbackConstants; import android.view.InputQueue; @@ -2224,7 +2224,13 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { if (mIsFloating) { layoutResource = com.android.internal.R.layout.dialog_title; } else if ((features & (1 << FEATURE_ACTION_BAR)) != 0) { - layoutResource = com.android.internal.R.layout.screen_action_bar; + Configuration config = getContext().getResources().getConfiguration(); + if ((config.screenLayout & Configuration.SCREENLAYOUT_SIZE_XLARGE) == + Configuration.SCREENLAYOUT_SIZE_XLARGE) { + layoutResource = com.android.internal.R.layout.screen_xlarge_action_bar; + } else { + layoutResource = com.android.internal.R.layout.screen_action_bar; + } } else { layoutResource = com.android.internal.R.layout.screen_title; } |