diff options
19 files changed, 1065 insertions, 362 deletions
diff --git a/api/current.xml b/api/current.xml index 4c7df55..5d5f8ac 100644 --- a/api/current.xml +++ b/api/current.xml @@ -1894,7 +1894,7 @@ type="int" transient="false" volatile="false" - value="16843549" + value="16843550" static="true" final="true" deprecated="not deprecated" @@ -1905,7 +1905,7 @@ type="int" transient="false" volatile="false" - value="16843548" + value="16843549" static="true" final="true" deprecated="not deprecated" @@ -1916,7 +1916,7 @@ type="int" transient="false" volatile="false" - value="16843550" + value="16843551" static="true" final="true" deprecated="not deprecated" @@ -4717,6 +4717,17 @@ visibility="public" > </field> +<field name="homeAsUpIndicator" + type="int" + transient="false" + volatile="false" + value="16843548" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="horizontalDivider" type="int" transient="false" @@ -9286,7 +9297,7 @@ type="int" transient="false" volatile="false" - value="16843552" + value="16843553" static="true" final="true" deprecated="not deprecated" @@ -9297,7 +9308,7 @@ type="int" transient="false" volatile="false" - value="16843551" + value="16843552" static="true" final="true" deprecated="not deprecated" @@ -19449,6 +19460,17 @@ visibility="public" > </method> +<method name="getNavigationItemCount" + return="int" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="getNavigationMode" return="int" abstract="true" @@ -19460,7 +19482,7 @@ visibility="public" > </method> -<method name="getSelectedNavigationItem" +<method name="getSelectedNavigationIndex" return="int" abstract="true" native="false" @@ -19471,6 +19493,17 @@ visibility="public" > </method> +<method name="getSelectedNavigationItem" + return="int" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="deprecated" + visibility="public" +> +</method> <method name="getSelectedTab" return="android.app.ActionBar.Tab" abstract="true" @@ -19493,6 +19526,19 @@ visibility="public" > </method> +<method name="getTabAt" + return="android.app.ActionBar.Tab" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="index" type="int"> +</parameter> +</method> <method name="getTitle" return="java.lang.CharSequence" abstract="true" @@ -19537,6 +19583,17 @@ visibility="public" > </method> +<method name="removeAllTabs" + return="void" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="removeTab" return="void" abstract="true" @@ -19596,11 +19653,39 @@ synchronized="false" static="false" final="false" + deprecated="deprecated" + visibility="public" +> +<parameter name="view" type="android.view.View"> +</parameter> +</method> +<method name="setCustomView" + return="void" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="view" type="android.view.View"> +</parameter> +</method> +<method name="setCustomView" + return="void" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" deprecated="not deprecated" visibility="public" > <parameter name="view" type="android.view.View"> </parameter> +<parameter name="layoutParams" type="android.app.ActionBar.LayoutParams"> +</parameter> </method> <method name="setDisplayOptions" return="void" @@ -19637,7 +19722,7 @@ synchronized="false" static="false" final="false" - deprecated="not deprecated" + deprecated="deprecated" visibility="public" > <parameter name="adapter" type="android.widget.SpinnerAdapter"> @@ -19652,7 +19737,7 @@ synchronized="false" static="false" final="false" - deprecated="not deprecated" + deprecated="deprecated" visibility="public" > <parameter name="adapter" type="android.widget.SpinnerAdapter"> @@ -19662,6 +19747,34 @@ <parameter name="defaultSelectedPosition" type="int"> </parameter> </method> +<method name="setListNavigationCallbacks" + return="void" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="adapter" type="android.widget.SpinnerAdapter"> +</parameter> +<parameter name="callback" type="android.app.ActionBar.NavigationCallback"> +</parameter> +</method> +<method name="setNavigationMode" + return="void" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="mode" type="int"> +</parameter> +</method> <method name="setSelectedNavigationItem" return="void" abstract="true" @@ -19682,7 +19795,7 @@ synchronized="false" static="false" final="false" - deprecated="not deprecated" + deprecated="deprecated" visibility="public" > </method> @@ -19719,7 +19832,7 @@ synchronized="false" static="false" final="false" - deprecated="not deprecated" + deprecated="deprecated" visibility="public" > </method> @@ -19764,6 +19877,39 @@ type="int" transient="false" volatile="false" + value="4096" + static="true" + final="true" + deprecated="deprecated" + visibility="public" +> +</field> +<field name="DISPLAY_HOME_AS_UP" + type="int" + transient="false" + volatile="false" + value="4" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="DISPLAY_SHOW_CUSTOM" + type="int" + transient="false" + volatile="false" + value="16" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="DISPLAY_SHOW_HOME" + type="int" + transient="false" + volatile="false" value="2" static="true" final="true" @@ -19771,22 +19917,22 @@ visibility="public" > </field> -<field name="DISPLAY_USE_LOGO" +<field name="DISPLAY_SHOW_TITLE" type="int" transient="false" volatile="false" - value="1" + value="8" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> -<field name="NAVIGATION_MODE_CUSTOM" +<field name="DISPLAY_USE_LOGO" type="int" transient="false" volatile="false" - value="3" + value="1" static="true" final="true" deprecated="not deprecated" @@ -19800,6 +19946,17 @@ value="1" static="true" final="true" + deprecated="deprecated" + visibility="public" +> +</field> +<field name="NAVIGATION_MODE_LIST" + type="int" + transient="false" + volatile="false" + value="1" + static="true" + final="true" deprecated="not deprecated" visibility="public" > @@ -19827,6 +19984,93 @@ > </field> </class> +<class name="ActionBar.LayoutParams" + extends="android.view.ViewGroup.MarginLayoutParams" + abstract="false" + static="true" + final="false" + deprecated="not deprecated" + visibility="public" +> +<constructor name="ActionBar.LayoutParams" + type="android.app.ActionBar.LayoutParams" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="c" type="android.content.Context"> +</parameter> +<parameter name="attrs" type="android.util.AttributeSet"> +</parameter> +</constructor> +<constructor name="ActionBar.LayoutParams" + type="android.app.ActionBar.LayoutParams" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="width" type="int"> +</parameter> +<parameter name="height" type="int"> +</parameter> +</constructor> +<constructor name="ActionBar.LayoutParams" + type="android.app.ActionBar.LayoutParams" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="width" type="int"> +</parameter> +<parameter name="height" type="int"> +</parameter> +<parameter name="gravity" type="int"> +</parameter> +</constructor> +<constructor name="ActionBar.LayoutParams" + type="android.app.ActionBar.LayoutParams" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="gravity" type="int"> +</parameter> +</constructor> +<constructor name="ActionBar.LayoutParams" + type="android.app.ActionBar.LayoutParams" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="source" type="android.app.ActionBar.LayoutParams"> +</parameter> +</constructor> +<constructor name="ActionBar.LayoutParams" + type="android.app.ActionBar.LayoutParams" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="source" type="android.view.ViewGroup.LayoutParams"> +</parameter> +</constructor> +<field name="gravity" + type="int" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</field> +</class> <interface name="ActionBar.NavigationCallback" abstract="true" static="true" @@ -19933,7 +20177,7 @@ > </method> <method name="setCustomView" - return="void" + return="android.app.ActionBar.Tab" abstract="true" native="false" synchronized="false" @@ -19946,7 +20190,7 @@ </parameter> </method> <method name="setIcon" - return="void" + return="android.app.ActionBar.Tab" abstract="true" native="false" synchronized="false" @@ -19959,7 +20203,7 @@ </parameter> </method> <method name="setTabListener" - return="void" + return="android.app.ActionBar.Tab" abstract="true" native="false" synchronized="false" @@ -19972,7 +20216,7 @@ </parameter> </method> <method name="setTag" - return="void" + return="android.app.ActionBar.Tab" abstract="true" native="false" synchronized="false" @@ -19985,7 +20229,7 @@ </parameter> </method> <method name="setText" - return="void" + return="android.app.ActionBar.Tab" abstract="true" native="false" synchronized="false" @@ -245127,7 +245371,7 @@ deprecated="not deprecated" visibility="public" > -<parameter name="arg0" type="T"> +<parameter name="t" type="T"> </parameter> </method> </interface> diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java index 7df9295..66038d8 100644 --- a/core/java/android/app/ActionBar.java +++ b/core/java/android/app/ActionBar.java @@ -16,8 +16,16 @@ package android.app; +import android.app.ActionBar.Tab; +import android.content.Context; +import android.content.res.TypedArray; import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.Gravity; import android.view.View; +import android.view.ViewDebug; +import android.view.ViewGroup; +import android.view.ViewGroup.MarginLayoutParams; import android.view.Window; import android.widget.SpinnerAdapter; @@ -37,9 +45,16 @@ public abstract class ActionBar { public static final int NAVIGATION_MODE_STANDARD = 0; /** - * Dropdown list navigation mode. Instead of static title text this mode - * presents a dropdown menu for navigation within the activity. + * List navigation mode. Instead of static title text this mode + * presents a list menu for navigation within the activity. + * e.g. this might be presented to the user as a dropdown list. */ + public static final int NAVIGATION_MODE_LIST = 1; + + /** + * @deprecated use NAVIGATION_MODE_LIST + */ + @Deprecated public static final int NAVIGATION_MODE_DROPDOWN_LIST = 1; /** @@ -47,24 +62,77 @@ public abstract class ActionBar { * presents a series of tabs for navigation within the activity. */ public static final int NAVIGATION_MODE_TABS = 2; - - /** - * Custom navigation mode. This navigation mode is set implicitly whenever - * a custom navigation view is set. See {@link #setCustomNavigationMode(View)}. - */ - public static final int NAVIGATION_MODE_CUSTOM = 3; /** * Use logo instead of icon if available. This flag will cause appropriate * navigation modes to use a wider logo in place of the standard icon. + * + * @see #setDisplayOptions(int) + * @see #setDisplayOptions(int, int) */ public static final int DISPLAY_USE_LOGO = 0x1; /** - * Hide 'home' elements in this action bar, leaving more space for other + * Show 'home' elements in this action bar, leaving more space for other * navigation elements. This includes logo and icon. + * + * @see #setDisplayOptions(int) + * @see #setDisplayOptions(int, int) + */ + public static final int DISPLAY_SHOW_HOME = 0x2; + + /** + * @deprecated Display flags are now positive for consistency - 'show' instead of 'hide'. + * Use DISPLAY_SHOW_HOME. + */ + @Deprecated + public static final int DISPLAY_HIDE_HOME = 0x1000; + + /** + * Display the 'home' element such that it appears as an 'up' affordance. + * e.g. show an arrow to the left indicating the action that will be taken. + * + * Set this flag if selecting the 'home' button in the action bar to return + * up by a single level in your UI rather than back to the top level or front page. + * + * @see #setDisplayOptions(int) + * @see #setDisplayOptions(int, int) + */ + public static final int DISPLAY_HOME_AS_UP = 0x4; + + /** + * Show the activity title and subtitle, if present. + * + * @see #setTitle(CharSequence) + * @see #setTitle(int) + * @see #setSubtitle(CharSequence) + * @see #setSubtitle(int) + * @see #setDisplayOptions(int) + * @see #setDisplayOptions(int, int) + */ + public static final int DISPLAY_SHOW_TITLE = 0x8; + + /** + * Show the custom view if one has been set. + * @see #setCustomView(View) + * @see #setDisplayOptions(int) + * @see #setDisplayOptions(int, int) + */ + public static final int DISPLAY_SHOW_CUSTOM = 0x10; + + /** + * Set the action bar into custom navigation mode, supplying a view + * for custom navigation. + * + * Custom navigation views appear between the application icon and + * any action buttons and may use any space available there. Common + * use cases for custom navigation views might include an auto-suggesting + * address bar for a browser or other navigation mechanisms that do not + * translate well to provided navigation modes. + * + * @param view Custom navigation view to place in the ActionBar. */ - public static final int DISPLAY_HIDE_HOME = 0x2; + public abstract void setCustomView(View view); /** * Set the action bar into custom navigation mode, supplying a view @@ -77,7 +145,15 @@ public abstract class ActionBar { * translate well to provided navigation modes. * * @param view Custom navigation view to place in the ActionBar. + * @param layoutParams How this custom view should layout in the bar. */ + public abstract void setCustomView(View view, LayoutParams layoutParams); + + /** + * @param view + * @deprecated Use {@link #setCustomView(View)} and {@link #setDisplayOptions(int)} instead. + */ + @Deprecated public abstract void setCustomNavigationMode(View view); /** @@ -89,11 +165,31 @@ public abstract class ActionBar { * within the dropdown navigation menu. * @param callback A NavigationCallback that will receive events when the user * selects a navigation item. + * @deprecated See setListNavigationCallbacks. */ + @Deprecated public abstract void setDropdownNavigationMode(SpinnerAdapter adapter, NavigationCallback callback); /** + * Set the adapter and navigation callback for list navigation mode. + * + * The supplied adapter will provide views for the expanded list as well as + * the currently selected item. (These may be displayed differently.) + * + * The supplied NavigationCallback will alert the application when the user + * changes the current list selection. + * + * @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 setListNavigationCallbacks(SpinnerAdapter adapter, + NavigationCallback callback); + + /** * Set the action bar into dropdown navigation mode and supply an adapter that will * provide views for navigation choices. * @@ -104,31 +200,51 @@ public abstract class ActionBar { * selects a navigation item. * @param defaultSelectedPosition Position within the provided adapter that should be * selected from the outset. + * @deprecated See setListNavigationCallbacks and setSelectedNavigationItem. */ + @Deprecated public abstract void setDropdownNavigationMode(SpinnerAdapter adapter, NavigationCallback callback, int defaultSelectedPosition); /** - * Set the selected navigation item in dropdown or tabbed navigation modes. + * Set the selected navigation item in list or tabbed navigation modes. * * @param position Position of the item to select. */ public abstract void setSelectedNavigationItem(int position); /** - * Get the position of the selected navigation item in dropdown or tabbed navigation modes. + * Get the position of the selected navigation item in list or tabbed navigation modes. * * @return Position of the selected item. + * @deprecated Use {@link #getSelectedNavigationIndex()} instead. */ + @Deprecated public abstract int getSelectedNavigationItem(); /** + * Get the position of the selected navigation item in list or tabbed navigation modes. + * + * @return Position of the selected item. + */ + public abstract int getSelectedNavigationIndex(); + + /** + * Get the number of navigation items present in the current navigation mode. + * + * @return Number of navigation items. + */ + public abstract int getNavigationItemCount(); + + /** * Set the action bar into standard navigation mode, using the currently set title * and/or subtitle. * * Standard navigation mode is default. The title is automatically set to the name of * your Activity on startup if an action bar is present. + * @deprecated See setNavigationMode */ + @Deprecated public abstract void setStandardNavigationMode(); /** @@ -181,10 +297,10 @@ public abstract class ActionBar { * Set selected display options. Only the options specified by mask will be changed. * To change all display option bits at once, see {@link #setDisplayOptions(int)}. * - * <p>Example: setDisplayOptions(0, DISPLAY_HIDE_HOME) will disable the - * {@link #DISPLAY_HIDE_HOME} option. - * setDisplayOptions(DISPLAY_HIDE_HOME, DISPLAY_HIDE_HOME | DISPLAY_USE_LOGO) - * will enable {@link #DISPLAY_HIDE_HOME} and disable {@link #DISPLAY_USE_LOGO}. + * <p>Example: setDisplayOptions(0, DISPLAY_SHOW_HOME) will disable the + * {@link #DISPLAY_SHOW_HOME} option. + * setDisplayOptions(DISPLAY_SHOW_HOME, DISPLAY_HIDE_HOME | DISPLAY_USE_LOGO) + * will enable {@link #DISPLAY_SHOW_HOME} and disable {@link #DISPLAY_USE_LOGO}. * * @param options A combination of the bits defined by the DISPLAY_ constants * defined in ActionBar. @@ -226,9 +342,8 @@ public abstract class ActionBar { * Returns the current navigation mode. The result will be one of: * <ul> * <li>{@link #NAVIGATION_MODE_STANDARD}</li> - * <li>{@link #NAVIGATION_MODE_DROPDOWN_LIST}</li> + * <li>{@link #NAVIGATION_MODE_LIST}</li> * <li>{@link #NAVIGATION_MODE_TABS}</li> - * <li>{@link #NAVIGATION_MODE_CUSTOM}</li> * </ul> * * @return The current navigation mode. @@ -241,7 +356,17 @@ public abstract class ActionBar { * @see #setCustomNavigationMode(View) */ public abstract int getNavigationMode(); - + + /** + * Set the current navigation mode. + * + * @param mode The new mode to set. + * @see #NAVIGATION_MODE_STANDARD + * @see #NAVIGATION_MODE_LIST + * @see #NAVIGATION_MODE_TABS + */ + public abstract void setNavigationMode(int mode); + /** * @return The current set of display options. */ @@ -254,6 +379,8 @@ public abstract class ActionBar { * @see #insertTab(Tab, int) * @see #removeTab(Tab) * @see #removeTabAt(int) + * + * @deprecated See {@link #setNavigationMode(int)} */ public abstract void setTabNavigationMode(); @@ -285,22 +412,31 @@ public abstract class ActionBar { public abstract void addTab(Tab tab, int position); /** - * Remove a tab from the action bar. + * Remove a tab from the action bar. If the removed tab was selected it will be deselected + * and another tab will be selected if present. * * @param tab The tab to remove */ public abstract void removeTab(Tab tab); /** - * Remove a tab from the action bar. + * Remove a tab from the action bar. If the removed tab was selected it will be deselected + * and another tab will be selected if present. * * @param position Position of the tab to remove */ public abstract void removeTabAt(int position); /** + * Remove all tabs from the action bar and deselect the current tab. + */ + public abstract void removeAllTabs(); + + /** * Select the specified tab. If it is not a child of this action bar it will be added. * + * <p>Note: If you want to select by index, use {@link #setSelectedNavigationItem(int)}.</p> + * * @param tab Tab to select */ public abstract void selectTab(Tab tab); @@ -314,6 +450,14 @@ public abstract class ActionBar { public abstract Tab getSelectedTab(); /** + * Returns the tab at the specified index. + * + * @param index Index value in the range 0-get + * @return + */ + public abstract Tab getTabAt(int index); + + /** * Retrieve the current height of the ActionBar. * * @return The ActionBar's height @@ -395,24 +539,27 @@ public abstract class ActionBar { * Set the icon displayed on this tab. * * @param icon The drawable to use as an icon + * @return The current instance for call chaining */ - public abstract void setIcon(Drawable icon); + public abstract Tab setIcon(Drawable icon); /** * Set the text displayed on this tab. Text may be truncated if there is not * room to display the entire string. * * @param text The text to display + * @return The current instance for call chaining */ - public abstract void setText(CharSequence text); + public abstract Tab setText(CharSequence text); /** * Set a custom view to be used for this tab. This overrides values set by * {@link #setText(CharSequence)} and {@link #setIcon(Drawable)}. * * @param view Custom view to be used as a tab. + * @return The current instance for call chaining */ - public abstract void setCustomView(View view); + public abstract Tab setCustomView(View view); /** * Retrieve a previously set custom view for this tab. @@ -425,8 +572,9 @@ public abstract class ActionBar { * Give this Tab an arbitrary object to hold for later use. * * @param obj Object to store + * @return The current instance for call chaining */ - public abstract void setTag(Object obj); + public abstract Tab setTag(Object obj); /** * @return This Tab's tag object. @@ -438,8 +586,9 @@ public abstract class ActionBar { * All tabs must have a TabListener set before being added to the ActionBar. * * @param listener Listener to handle tab selection events + * @return The current instance for call chaining */ - public abstract void setTabListener(TabListener listener); + public abstract Tab setTabListener(TabListener listener); /** * Select this tab. Only valid if the tab has been added to the action bar. @@ -481,4 +630,65 @@ public abstract class ActionBar { */ public void onTabReselected(Tab tab, FragmentTransaction ft); } + + /** + * Per-child layout information associated with action bar custom views. + * + * @attr ref android.R.styleable#ActionBar_LayoutParams_layout_gravity + */ + public static class LayoutParams extends MarginLayoutParams { + /** + * Gravity for the view associated with these LayoutParams. + * + * @see android.view.Gravity + */ + @ViewDebug.ExportedProperty(category = "layout", mapping = { + @ViewDebug.IntToString(from = -1, to = "NONE"), + @ViewDebug.IntToString(from = Gravity.NO_GRAVITY, to = "NONE"), + @ViewDebug.IntToString(from = Gravity.TOP, to = "TOP"), + @ViewDebug.IntToString(from = Gravity.BOTTOM, to = "BOTTOM"), + @ViewDebug.IntToString(from = Gravity.LEFT, to = "LEFT"), + @ViewDebug.IntToString(from = Gravity.RIGHT, to = "RIGHT"), + @ViewDebug.IntToString(from = Gravity.CENTER_VERTICAL, to = "CENTER_VERTICAL"), + @ViewDebug.IntToString(from = Gravity.FILL_VERTICAL, to = "FILL_VERTICAL"), + @ViewDebug.IntToString(from = Gravity.CENTER_HORIZONTAL, to = "CENTER_HORIZONTAL"), + @ViewDebug.IntToString(from = Gravity.FILL_HORIZONTAL, to = "FILL_HORIZONTAL"), + @ViewDebug.IntToString(from = Gravity.CENTER, to = "CENTER"), + @ViewDebug.IntToString(from = Gravity.FILL, to = "FILL") + }) + public int gravity = -1; + + public LayoutParams(Context c, AttributeSet attrs) { + super(c, attrs); + + TypedArray a = c.obtainStyledAttributes(attrs, + com.android.internal.R.styleable.ActionBar_LayoutParams); + gravity = a.getInt( + com.android.internal.R.styleable.ActionBar_LayoutParams_layout_gravity, -1); + } + + public LayoutParams(int width, int height) { + super(width, height); + this.gravity = Gravity.CENTER_VERTICAL | Gravity.LEFT; + } + + public LayoutParams(int width, int height, int gravity) { + super(width, height); + this.gravity = gravity; + } + + public LayoutParams(int gravity) { + this(WRAP_CONTENT, MATCH_PARENT, gravity); + } + + public LayoutParams(LayoutParams source) { + super(source); + + this.gravity = source.gravity; + } + + public LayoutParams(ViewGroup.LayoutParams source) { + super(source); + } + } } diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index a29acf1..5ce4cd6 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -265,7 +265,11 @@ class ContextImpl extends Context { public Resources.Theme getTheme() { if (mTheme == null) { if (mThemeResource == 0) { - mThemeResource = com.android.internal.R.style.Theme; + final Context outerContext = getOuterContext(); + mThemeResource = (outerContext.getApplicationInfo().targetSdkVersion + >= Build.VERSION_CODES.HONEYCOMB) + ? com.android.internal.R.style.Theme_Holo + : com.android.internal.R.style.Theme; } mTheme = mResources.newTheme(); mTheme.applyStyle(mThemeResource, true); diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java index 3015363..f4a041c 100644 --- a/core/java/com/android/internal/app/ActionBarImpl.java +++ b/core/java/com/android/internal/app/ActionBarImpl.java @@ -52,9 +52,6 @@ import java.util.ArrayList; public class ActionBarImpl extends ActionBar { private static final int NORMAL_VIEW = 0; private static final int CONTEXT_VIEW = 1; - - private static final int TAB_SWITCH_SHOW_HIDE = 0; - private static final int TAB_SWITCH_ADD_REMOVE = 1; private Context mContext; private Activity mActivity; @@ -67,9 +64,7 @@ public class ActionBarImpl extends ActionBar { private ArrayList<TabImpl> mTabs = new ArrayList<TabImpl>(); - private int mTabContainerViewId = android.R.id.content; private TabImpl mSelectedTab; - private int mTabSwitchMode = TAB_SWITCH_ADD_REMOVE; private ActionMode mActionMode; @@ -133,7 +128,9 @@ public class ActionBarImpl extends ActionBar { public void setCustomNavigationMode(View view) { cleanupTabs(); - mActionView.setCustomNavigationView(view); + setCustomView(view); + setDisplayOptions(DISPLAY_SHOW_CUSTOM, DISPLAY_SHOW_CUSTOM | DISPLAY_SHOW_TITLE); + mActionView.setNavigationMode(NAVIGATION_MODE_STANDARD); mActionView.setCallback(null); } @@ -144,16 +141,17 @@ public class ActionBarImpl extends ActionBar { public void setDropdownNavigationMode(SpinnerAdapter adapter, NavigationCallback callback, int defaultSelectedPosition) { cleanupTabs(); - mActionView.setNavigationMode(NAVIGATION_MODE_DROPDOWN_LIST); - mActionView.setDropdownAdapter(adapter); + setDisplayOptions(0, DISPLAY_SHOW_CUSTOM | DISPLAY_SHOW_TITLE); + mActionView.setNavigationMode(NAVIGATION_MODE_LIST); + setListNavigationCallbacks(adapter, callback); if (defaultSelectedPosition >= 0) { mActionView.setDropdownSelectedPosition(defaultSelectedPosition); } - mActionView.setCallback(callback); } public void setStandardNavigationMode() { cleanupTabs(); + setDisplayOptions(DISPLAY_SHOW_TITLE, DISPLAY_SHOW_TITLE | DISPLAY_SHOW_CUSTOM); mActionView.setNavigationMode(NAVIGATION_MODE_STANDARD); mActionView.setCallback(null); } @@ -163,24 +161,21 @@ public class ActionBarImpl extends ActionBar { case NAVIGATION_MODE_TABS: selectTab(mTabs.get(position)); break; - case NAVIGATION_MODE_DROPDOWN_LIST: + case NAVIGATION_MODE_LIST: mActionView.setDropdownSelectedPosition(position); break; default: throw new IllegalStateException( - "setSelectedNavigationItem not valid for current navigation mode"); + "setSelectedNavigationIndex not valid for current navigation mode"); } } public int getSelectedNavigationItem() { - switch (mActionView.getNavigationMode()) { - case NAVIGATION_MODE_TABS: - return mSelectedTab.getPosition(); - case NAVIGATION_MODE_DROPDOWN_LIST: - return mActionView.getDropdownSelectedPosition(); - default: - return -1; - } + return getSelectedNavigationIndex(); + } + + public void removeAllTabs() { + cleanupTabs(); } private void cleanupTabs() { @@ -321,6 +316,7 @@ public class ActionBarImpl extends ActionBar { throw new IllegalStateException( "Tab navigation mode cannot be used outside of an Activity"); } + setDisplayOptions(0, DISPLAY_SHOW_TITLE | DISPLAY_SHOW_CUSTOM); mActionView.setNavigationMode(NAVIGATION_MODE_TABS); } @@ -510,8 +506,9 @@ public class ActionBarImpl extends ActionBar { } @Override - public void setTag(Object tag) { + public Tab setTag(Object tag) { mTag = tag; + return this; } public ActionBar.TabListener getCallback() { @@ -519,8 +516,9 @@ public class ActionBarImpl extends ActionBar { } @Override - public void setTabListener(ActionBar.TabListener callback) { + public Tab setTabListener(ActionBar.TabListener callback) { mCallback = callback; + return this; } @Override @@ -529,8 +527,9 @@ public class ActionBarImpl extends ActionBar { } @Override - public void setCustomView(View view) { + public Tab setCustomView(View view) { mCustomView = view; + return this; } @Override @@ -553,13 +552,15 @@ public class ActionBarImpl extends ActionBar { } @Override - public void setIcon(Drawable icon) { + public Tab setIcon(Drawable icon) { mIcon = icon; + return this; } @Override - public void setText(CharSequence text) { + public Tab setText(CharSequence text) { mText = text; + return this; } @Override @@ -567,4 +568,56 @@ public class ActionBarImpl extends ActionBar { selectTab(this); } } + + @Override + public void setCustomView(View view) { + mActionView.setCustomNavigationView(view); + } + + @Override + public void setCustomView(View view, LayoutParams layoutParams) { + view.setLayoutParams(layoutParams); + mActionView.setCustomNavigationView(view); + } + + @Override + public void setListNavigationCallbacks(SpinnerAdapter adapter, NavigationCallback callback) { + mActionView.setDropdownAdapter(adapter); + mActionView.setCallback(callback); + } + + @Override + public int getSelectedNavigationIndex() { + switch (mActionView.getNavigationMode()) { + case NAVIGATION_MODE_TABS: + return mSelectedTab.getPosition(); + case NAVIGATION_MODE_LIST: + return mActionView.getDropdownSelectedPosition(); + default: + return -1; + } + } + + @Override + public int getNavigationItemCount() { + switch (mActionView.getNavigationMode()) { + case NAVIGATION_MODE_TABS: + return mTabs.size(); + case NAVIGATION_MODE_LIST: + SpinnerAdapter adapter = mActionView.getDropdownAdapter(); + return adapter != null ? adapter.getCount() : 0; + default: + return 0; + } + } + + @Override + public void setNavigationMode(int mode) { + mActionView.setNavigationMode(mode); + } + + @Override + public Tab getTabAt(int index) { + return mTabs.get(index); + } } diff --git a/core/java/com/android/internal/view/menu/ActionMenuView.java b/core/java/com/android/internal/view/menu/ActionMenuView.java index 2888074..621defe 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuView.java +++ b/core/java/com/android/internal/view/menu/ActionMenuView.java @@ -24,10 +24,10 @@ import android.util.AttributeSet; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; +import android.view.ViewParent; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.LinearLayout.LayoutParams; import java.util.ArrayList; @@ -169,6 +169,10 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo final MenuItemImpl itemData = itemsToShow.get(i); final View actionView = itemData.getActionView(); if (actionView != null) { + final ViewParent parent = actionView.getParent(); + if (parent instanceof ViewGroup) { + ((ViewGroup) parent).removeView(actionView); + } addView(actionView, makeActionViewLayoutParams()); } else { needsDivider = addItemView(i == 0 || !needsDivider, diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java index 38f76d3..e93c414 100644 --- a/core/java/com/android/internal/widget/ActionBarContextView.java +++ b/core/java/com/android/internal/widget/ActionBarContextView.java @@ -26,9 +26,6 @@ import android.view.ActionMode; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; -import android.widget.ButtonGroup; -import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TextView; diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java index 4c3bba1..be96e48 100644 --- a/core/java/com/android/internal/widget/ActionBarView.java +++ b/core/java/com/android/internal/widget/ActionBarView.java @@ -26,20 +26,21 @@ import android.app.ActionBar.NavigationCallback; import android.app.Activity; import android.content.Context; import android.content.pm.ApplicationInfo; +import android.content.pm.ComponentInfo; import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.TypedArray; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Drawable; import android.text.TextUtils.TruncateAt; import android.util.AttributeSet; -import android.util.DisplayMetrics; +import android.util.Log; import android.view.ActionMode; import android.view.Gravity; import android.view.LayoutInflater; import android.view.Menu; import android.view.View; import android.view.ViewGroup; +import android.view.ViewParent; import android.widget.AdapterView; import android.widget.HorizontalScrollView; import android.widget.ImageView; @@ -63,19 +64,27 @@ public class ActionBarView extends ViewGroup { * Display options that require re-layout as opposed to a simple invalidate */ private static final int DISPLAY_RELAYOUT_MASK = - ActionBar.DISPLAY_HIDE_HOME | - ActionBar.DISPLAY_USE_LOGO; + ActionBar.DISPLAY_SHOW_HOME | + ActionBar.DISPLAY_USE_LOGO | + ActionBar.DISPLAY_HOME_AS_UP | + ActionBar.DISPLAY_SHOW_CUSTOM | + ActionBar.DISPLAY_SHOW_TITLE; + + private static final int DEFAULT_CUSTOM_GRAVITY = Gravity.LEFT | Gravity.CENTER_VERTICAL; private final int mContentHeight; private int mNavigationMode; - private int mDisplayOptions; + private int mDisplayOptions = ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_HOME_AS_UP; private CharSequence mTitle; private CharSequence mSubtitle; private Drawable mIcon; private Drawable mLogo; private Drawable mDivider; + private Drawable mHomeAsUpIndicator; + private LinearLayout mHomeLayout; + private ImageView mHomeAsUpView; private ImageView mIconView; private ImageView mLogoView; private LinearLayout mTitleLayout; @@ -98,7 +107,8 @@ public class ActionBarView extends ViewGroup { private ActionBarContextView mContextView; private ActionMenuItem mLogoNavItem; - + + private SpinnerAdapter mSpinnerAdapter; private NavigationCallback mCallback; private final AdapterView.OnItemSelectedListener mNavItemSelectedListener = @@ -122,30 +132,56 @@ public class ActionBarView extends ViewGroup { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ActionBar); - final int colorFilter = a.getColor(R.styleable.ActionBar_colorFilter, 0); - - if (colorFilter != 0) { - final Drawable d = getBackground(); - d.setDither(true); - d.setColorFilter(new PorterDuffColorFilter(colorFilter, PorterDuff.Mode.OVERLAY)); - } - - ApplicationInfo info = context.getApplicationInfo(); + ApplicationInfo appInfo = context.getApplicationInfo(); PackageManager pm = context.getPackageManager(); mNavigationMode = a.getInt(R.styleable.ActionBar_navigationMode, ActionBar.NAVIGATION_MODE_STANDARD); mTitle = a.getText(R.styleable.ActionBar_title); mSubtitle = a.getText(R.styleable.ActionBar_subtitle); - mDisplayOptions = a.getInt(R.styleable.ActionBar_displayOptions, DISPLAY_DEFAULT); mLogo = a.getDrawable(R.styleable.ActionBar_logo); if (mLogo == null) { - mLogo = info.loadLogo(pm); + if (context instanceof Activity) { + try { + mLogo = pm.getActivityLogo(((Activity) context).getComponentName()); + } catch (NameNotFoundException e) { + Log.e(TAG, "Activity component name not found!", e); + } + } + if (mLogo == null) { + mLogo = appInfo.loadLogo(pm); + } } + mIcon = a.getDrawable(R.styleable.ActionBar_icon); if (mIcon == null) { - mIcon = info.loadIcon(pm); + if (context instanceof Activity) { + try { + mIcon = pm.getActivityIcon(((Activity) context).getComponentName()); + } catch (NameNotFoundException e) { + Log.e(TAG, "Activity component name not found!", e); + } + } + if (mIcon == null) { + mIcon = appInfo.loadIcon(pm); + } } + + mHomeLayout = new LinearLayout(context, null, + com.android.internal.R.attr.actionButtonStyle); + mHomeLayout.setClickable(true); + mHomeLayout.setFocusable(true); + mHomeLayout.setOnClickListener(mHomeClickListener); + mHomeLayout.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, + LayoutParams.MATCH_PARENT)); + + mHomeAsUpIndicator = a.getDrawable(R.styleable.ActionBar_homeAsUpIndicator); + + mHomeAsUpView = new ImageView(context); + mHomeAsUpView.setImageDrawable(mHomeAsUpIndicator); + mHomeAsUpView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, + LayoutParams.MATCH_PARENT)); + mHomeLayout.addView(mHomeAsUpView); Drawable background = a.getDrawable(R.styleable.ActionBar_background); if (background != null) { @@ -155,11 +191,14 @@ public class ActionBarView extends ViewGroup { mTitleStyleRes = a.getResourceId(R.styleable.ActionBar_titleTextStyle, 0); mSubtitleStyleRes = a.getResourceId(R.styleable.ActionBar_subtitleTextStyle, 0); + setDisplayOptions(a.getInt(R.styleable.ActionBar_displayOptions, DISPLAY_DEFAULT)); + final int customNavId = a.getResourceId(R.styleable.ActionBar_customNavigationLayout, 0); if (customNavId != 0) { LayoutInflater inflater = LayoutInflater.from(context); mCustomNavView = (View) inflater.inflate(customNavId, null); - mNavigationMode = ActionBar.NAVIGATION_MODE_CUSTOM; + mNavigationMode = ActionBar.NAVIGATION_MODE_STANDARD; + setDisplayOptions(mDisplayOptions | ActionBar.DISPLAY_SHOW_CUSTOM); } mContentHeight = a.getLayoutDimension(R.styleable.ActionBar_height, 0); @@ -241,9 +280,13 @@ public class ActionBarView extends ViewGroup { } public void setCustomNavigationView(View view) { + final boolean showCustom = (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0; + if (mCustomNavView != null && showCustom) { + removeView(mCustomNavView); + } mCustomNavView = view; - if (view != null) { - setNavigationMode(ActionBar.NAVIGATION_MODE_CUSTOM); + if (mCustomNavView != null && showCustom) { + addView(mCustomNavView); } } @@ -296,15 +339,43 @@ public class ActionBarView extends ViewGroup { } public void setDisplayOptions(int options) { + // TODO Remove this once DISPLAY_HIDE_HOME is removed + if ((options & ActionBar.DISPLAY_HIDE_HOME) != 0) { + options &= ~(ActionBar.DISPLAY_HIDE_HOME | ActionBar.DISPLAY_SHOW_HOME); + } + // End TODO + final int flagsChanged = options ^ mDisplayOptions; mDisplayOptions = options; if ((flagsChanged & DISPLAY_RELAYOUT_MASK) != 0) { - final int vis = (options & ActionBar.DISPLAY_HIDE_HOME) != 0 ? GONE : VISIBLE; - if (mLogoView != null) { - mLogoView.setVisibility(vis); + final int vis = (options & ActionBar.DISPLAY_SHOW_HOME) != 0 ? VISIBLE : GONE; + mHomeLayout.setVisibility(vis); + + if ((flagsChanged & ActionBar.DISPLAY_HOME_AS_UP) != 0) { + mHomeAsUpView.setVisibility((options & ActionBar.DISPLAY_HOME_AS_UP) != 0 + ? VISIBLE : GONE); } - if (mIconView != null) { - mIconView.setVisibility(vis); + + if (mLogoView != null && (flagsChanged & ActionBar.DISPLAY_USE_LOGO) != 0) { + final boolean logoVis = (options & ActionBar.DISPLAY_USE_LOGO) != 0; + mLogoView.setVisibility(logoVis ? VISIBLE : GONE); + mIconView.setVisibility(logoVis ? GONE : VISIBLE); + } + + if ((flagsChanged & ActionBar.DISPLAY_SHOW_TITLE) != 0) { + if ((options & ActionBar.DISPLAY_SHOW_TITLE) != 0) { + initTitle(); + } else { + removeView(mTitleLayout); + } + } + + if ((flagsChanged & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomNavView != null) { + if ((options & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) { + addView(mCustomNavView); + } else { + removeView(mCustomNavView); + } } requestLayout(); @@ -317,52 +388,27 @@ public class ActionBarView extends ViewGroup { final int oldMode = mNavigationMode; if (mode != oldMode) { switch (oldMode) { - case ActionBar.NAVIGATION_MODE_STANDARD: - if (mTitleLayout != null) { - removeView(mTitleLayout); - mTitleLayout = null; - mTitleView = null; - mSubtitleView = null; - } - break; - case ActionBar.NAVIGATION_MODE_DROPDOWN_LIST: + case ActionBar.NAVIGATION_MODE_LIST: if (mSpinner != null) { removeView(mSpinner); - mSpinner = null; - } - break; - case ActionBar.NAVIGATION_MODE_CUSTOM: - if (mCustomNavView != null) { - removeView(mCustomNavView); - mCustomNavView = null; } break; case ActionBar.NAVIGATION_MODE_TABS: if (mTabLayout != null) { removeView(mTabScrollView); - mTabLayout = null; - mTabScrollView = null; } } switch (mode) { - case ActionBar.NAVIGATION_MODE_STANDARD: - initTitle(); - break; - case ActionBar.NAVIGATION_MODE_DROPDOWN_LIST: + case ActionBar.NAVIGATION_MODE_LIST: mSpinner = new Spinner(mContext, null, com.android.internal.R.attr.actionDropDownStyle); + mSpinner.setAdapter(mSpinnerAdapter); mSpinner.setOnItemSelectedListener(mNavItemSelectedListener); addView(mSpinner); break; - case ActionBar.NAVIGATION_MODE_CUSTOM: - addView(mCustomNavView); - break; case ActionBar.NAVIGATION_MODE_TABS: - mTabScrollView = new HorizontalScrollView(getContext()); - mTabLayout = new LinearLayout(getContext(), null, - com.android.internal.R.attr.actionBarTabBarStyle); - mTabScrollView.addView(mTabLayout); + ensureTabsExist(); addView(mTabScrollView); break; } @@ -371,8 +417,24 @@ public class ActionBarView extends ViewGroup { } } + private void ensureTabsExist() { + if (mTabScrollView == null) { + mTabScrollView = new HorizontalScrollView(getContext()); + mTabLayout = new LinearLayout(getContext(), null, + com.android.internal.R.attr.actionBarTabBarStyle); + mTabScrollView.addView(mTabLayout); + } + } + public void setDropdownAdapter(SpinnerAdapter adapter) { - mSpinner.setAdapter(adapter); + mSpinnerAdapter = adapter; + if (mSpinner != null) { + mSpinner.setAdapter(adapter); + } + } + + public SpinnerAdapter getDropdownAdapter() { + return mSpinnerAdapter; } public void setDropdownSelectedPosition(int position) { @@ -407,6 +469,7 @@ public class ActionBarView extends ViewGroup { } public void addTab(ActionBar.Tab tab) { + ensureTabsExist(); final boolean isFirst = mTabLayout.getChildCount() == 0; View tabView = createTabView(tab); mTabLayout.addView(tabView); @@ -416,6 +479,7 @@ public class ActionBarView extends ViewGroup { } public void addTab(ActionBar.Tab tab, int position) { + ensureTabsExist(); final boolean isFirst = mTabLayout.getChildCount() == 0; final TabView tabView = createTabView(tab); mTabLayout.addView(tabView, position); @@ -425,46 +489,50 @@ public class ActionBarView extends ViewGroup { } public void removeTabAt(int position) { - mTabLayout.removeViewAt(position); + if (mTabLayout != null) { + mTabLayout.removeViewAt(position); + } } @Override protected LayoutParams generateDefaultLayoutParams() { // Used by custom nav views if they don't supply layout params. Everything else // added to an ActionBarView should have them already. - return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); + return new ActionBar.LayoutParams(DEFAULT_CUSTOM_GRAVITY); } @Override protected void onFinishInflate() { super.onFinishInflate(); - if ((mDisplayOptions & ActionBar.DISPLAY_HIDE_HOME) == 0) { - if (mLogo != null && (mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) != 0) { - mLogoView = new ImageView(getContext(), null, - com.android.internal.R.attr.actionButtonStyle); - mLogoView.setAdjustViewBounds(true); - mLogoView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, - LayoutParams.MATCH_PARENT)); - mLogoView.setImageDrawable(mLogo); - mLogoView.setClickable(true); - mLogoView.setFocusable(true); - mLogoView.setOnClickListener(mHomeClickListener); - addView(mLogoView); - } else if (mIcon != null) { - mIconView = new ImageView(getContext(), null, - com.android.internal.R.attr.actionButtonStyle); - mIconView.setAdjustViewBounds(true); - mIconView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, - LayoutParams.MATCH_PARENT)); - mIconView.setImageDrawable(mIcon); - mIconView.setClickable(true); - mIconView.setFocusable(true); - mIconView.setOnClickListener(mHomeClickListener); - addView(mIconView); - } + final Context context = getContext(); + + if (mLogo != null) { + mLogoView = new ImageView(context); + mLogoView.setScaleType(ImageView.ScaleType.CENTER); + mLogoView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, + LayoutParams.MATCH_PARENT)); + mLogoView.setImageDrawable(mLogo); + mLogoView.setVisibility((mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) != 0 + ? VISIBLE : GONE); + mHomeLayout.addView(mLogoView); } + if (mIcon != null) { + mIconView = new ImageView(context, null, + com.android.internal.R.attr.actionButtonStyle); + mIconView.setScaleType(ImageView.ScaleType.CENTER); + mIconView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, + LayoutParams.MATCH_PARENT)); + mIconView.setImageDrawable(mIcon); + mIconView.setVisibility( + (mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) == 0 || mLogo == null + ? VISIBLE : GONE); + mHomeLayout.addView(mIconView); + } + + addView(mHomeLayout); + switch (mNavigationMode) { case ActionBar.NAVIGATION_MODE_STANDARD: if (mLogoView == null) { @@ -472,19 +540,23 @@ public class ActionBarView extends ViewGroup { } break; - case ActionBar.NAVIGATION_MODE_DROPDOWN_LIST: + case ActionBar.NAVIGATION_MODE_LIST: throw new UnsupportedOperationException( - "Inflating dropdown list navigation isn't supported yet!"); + "Inflating list navigation isn't supported yet!"); case ActionBar.NAVIGATION_MODE_TABS: throw new UnsupportedOperationException( "Inflating tab navigation isn't supported yet!"); - - case ActionBar.NAVIGATION_MODE_CUSTOM: - if (mCustomNavView != null) { + } + + if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) { + final ViewParent parent = mCustomNavView.getParent(); + if (parent != this) { + if (parent instanceof ViewGroup) { + ((ViewGroup) parent).removeView(mCustomNavView); + } addView(mCustomNavView); } - break; } } @@ -513,6 +585,7 @@ public class ActionBarView extends ViewGroup { } public void setTabSelected(int position) { + ensureTabsExist(); final int tabCount = mTabLayout.getChildCount(); for (int i = 0; i < tabCount; i++) { final View child = mTabLayout.getChildAt(i); @@ -544,57 +617,40 @@ public class ActionBarView extends ViewGroup { mContentHeight : MeasureSpec.getSize(heightMeasureSpec); final int verticalPadding = getPaddingTop() + getPaddingBottom(); - int availableWidth = contentWidth - getPaddingLeft() - getPaddingRight(); + final int paddingLeft = getPaddingLeft(); + final int paddingRight = getPaddingRight(); final int height = maxHeight - verticalPadding; final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST); - if (mLogoView != null && mLogoView.getVisibility() != GONE) { - availableWidth = measureChildView(mLogoView, availableWidth, childSpecHeight, 0); - } - if (mIconView != null && mIconView.getVisibility() != GONE) { - availableWidth = measureChildView(mIconView, availableWidth, childSpecHeight, 0); + int availableWidth = contentWidth - paddingLeft - paddingRight; + int leftOfCenter = availableWidth / 2; + int rightOfCenter = leftOfCenter; + + if (mHomeLayout.getVisibility() != GONE) { + availableWidth = measureChildView(mHomeLayout, availableWidth, childSpecHeight, 0); + leftOfCenter -= mHomeLayout.getMeasuredWidth(); } if (mMenuView != null) { availableWidth = measureChildView(mMenuView, availableWidth, childSpecHeight, 0); + rightOfCenter -= mMenuView.getMeasuredWidth(); } - + + if (mTitleLayout != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) { + availableWidth = measureChildView(mTitleLayout, availableWidth, childSpecHeight, 0); + leftOfCenter -= mTitleLayout.getMeasuredWidth(); + } + switch (mNavigationMode) { - case ActionBar.NAVIGATION_MODE_STANDARD: - if (mTitleLayout != null) { - measureChildView(mTitleLayout, availableWidth, childSpecHeight, 0); - } - break; - case ActionBar.NAVIGATION_MODE_DROPDOWN_LIST: + case ActionBar.NAVIGATION_MODE_LIST: if (mSpinner != null) { mSpinner.measure( MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST)); - } - break; - case ActionBar.NAVIGATION_MODE_CUSTOM: - if (mCustomNavView != null) { - LayoutParams lp = mCustomNavView.getLayoutParams(); - final int customNavWidthMode = lp.width != LayoutParams.WRAP_CONTENT ? - MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; - final int customNavWidth = lp.width >= 0 ? - Math.min(lp.width, availableWidth) : availableWidth; - - // If the action bar is wrapping to its content height, don't allow a custom - // view to MATCH_PARENT. - int customNavHeightMode; - if (mContentHeight <= 0) { - customNavHeightMode = MeasureSpec.AT_MOST; - } else { - customNavHeightMode = lp.height != LayoutParams.WRAP_CONTENT ? - MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; - } - final int customNavHeight = lp.height >= 0 ? - Math.min(lp.height, height) : height; - mCustomNavView.measure( - MeasureSpec.makeMeasureSpec(customNavWidth, customNavWidthMode), - MeasureSpec.makeMeasureSpec(customNavHeight, customNavHeightMode)); + final int spinnerWidth = mSpinner.getMeasuredWidth(); + availableWidth -= spinnerWidth; + leftOfCenter -= spinnerWidth; } break; case ActionBar.NAVIGATION_MODE_TABS: @@ -602,10 +658,56 @@ public class ActionBarView extends ViewGroup { mTabScrollView.measure( MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); + final int tabWidth = mTabScrollView.getMeasuredWidth(); + availableWidth -= tabWidth; + leftOfCenter -= tabWidth; } break; } + if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomNavView != null) { + final LayoutParams lp = generateLayoutParams(mCustomNavView.getLayoutParams()); + final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ? + (ActionBar.LayoutParams) lp : null; + + int horizontalMargin = 0; + int verticalMargin = 0; + if (ablp != null) { + horizontalMargin = ablp.leftMargin + ablp.rightMargin; + verticalMargin = ablp.topMargin + ablp.bottomMargin; + } + + // If the action bar is wrapping to its content height, don't allow a custom + // view to MATCH_PARENT. + int customNavHeightMode; + if (mContentHeight <= 0) { + customNavHeightMode = MeasureSpec.AT_MOST; + } else { + customNavHeightMode = lp.height != LayoutParams.WRAP_CONTENT ? + MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; + } + final int customNavHeight = Math.max(0, + (lp.height >= 0 ? Math.min(lp.height, height) : height) - verticalMargin); + + final int customNavWidthMode = lp.width != LayoutParams.WRAP_CONTENT ? + MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; + int customNavWidth = Math.max(0, + (lp.width >= 0 ? Math.min(lp.width, availableWidth) : availableWidth) + - horizontalMargin); + final int hgrav = (ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY) & + Gravity.HORIZONTAL_GRAVITY_MASK; + + // Centering a custom view is treated specially; we try to center within the whole + // action bar rather than in the available space. + if (hgrav == Gravity.CENTER_HORIZONTAL && lp.width == LayoutParams.MATCH_PARENT) { + customNavWidth = Math.min(leftOfCenter, rightOfCenter) * 2; + } + + mCustomNavView.measure( + MeasureSpec.makeMeasureSpec(customNavWidth, customNavWidthMode), + MeasureSpec.makeMeasureSpec(customNavHeight, customNavHeightMode)); + } + if (mContentHeight <= 0) { int measuredHeight = 0; final int count = getChildCount(); @@ -642,39 +744,89 @@ public class ActionBarView extends ViewGroup { final int y = getPaddingTop(); final int contentHeight = b - t - getPaddingTop() - getPaddingBottom(); - if (mLogoView != null && mLogoView.getVisibility() != GONE) { - x += positionChild(mLogoView, x, y, contentHeight); - } - if (mIconView != null && mIconView.getVisibility() != GONE) { - x += positionChild(mIconView, x, y, contentHeight); + if (mHomeLayout.getVisibility() != GONE) { + x += positionChild(mHomeLayout, x, y, contentHeight); } + if (mTitleLayout != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) { + x += positionChild(mTitleLayout, x, y, contentHeight); + } + switch (mNavigationMode) { case ActionBar.NAVIGATION_MODE_STANDARD: - if (mTitleLayout != null) { - x += positionChild(mTitleLayout, x, y, contentHeight); - } break; - case ActionBar.NAVIGATION_MODE_DROPDOWN_LIST: + case ActionBar.NAVIGATION_MODE_LIST: if (mSpinner != null) { x += positionChild(mSpinner, x, y, contentHeight); } break; - case ActionBar.NAVIGATION_MODE_CUSTOM: - if (mCustomNavView != null) { - x += positionChild(mCustomNavView, x, y, contentHeight); - } - break; case ActionBar.NAVIGATION_MODE_TABS: if (mTabScrollView != null) { x += positionChild(mTabScrollView, x, y, contentHeight); } } - x = r - l - getPaddingRight(); - + int menuLeft = r - l - getPaddingRight(); if (mMenuView != null) { - x -= positionChildInverse(mMenuView, x, y, contentHeight); + positionChildInverse(mMenuView, menuLeft, y, contentHeight); + menuLeft -= mMenuView.getMeasuredWidth(); + } + + if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) { + LayoutParams lp = mCustomNavView.getLayoutParams(); + final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ? + (ActionBar.LayoutParams) lp : null; + + final int gravity = ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY; + final int navWidth = mCustomNavView.getMeasuredWidth(); + + int topMargin = 0; + int bottomMargin = 0; + if (ablp != null) { + x += ablp.leftMargin; + menuLeft -= ablp.rightMargin; + topMargin = ablp.topMargin; + bottomMargin = ablp.bottomMargin; + } + + int hgravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK; + // See if we actually have room to truly center; if not push against left or right. + if (hgravity == Gravity.CENTER_HORIZONTAL) { + final int centeredLeft = ((mRight - mLeft) - navWidth) / 2; + if (centeredLeft < x) { + hgravity = Gravity.LEFT; + } else if (centeredLeft + navWidth > menuLeft) { + hgravity = Gravity.RIGHT; + } + } + + int xpos = 0; + switch (hgravity) { + case Gravity.CENTER_HORIZONTAL: + xpos = ((mRight - mLeft) - navWidth) / 2; + break; + case Gravity.LEFT: + xpos = x; + break; + case Gravity.RIGHT: + xpos = menuLeft - navWidth; + break; + } + + int ypos = 0; + switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) { + case Gravity.CENTER_VERTICAL: + ypos = ((mBottom - mTop) - mCustomNavView.getMeasuredHeight()) / 2; + break; + case Gravity.TOP: + ypos = getPaddingTop() + topMargin; + break; + case Gravity.BOTTOM: + ypos = getHeight() - getPaddingBottom() - mCustomNavView.getMeasuredHeight() + - bottomMargin; + break; + } + x += positionChild(mCustomNavView, xpos, ypos, contentHeight); } } diff --git a/core/res/res/drawable-hdpi/ic_ab_back_holo_dark.png b/core/res/res/drawable-hdpi/ic_ab_back_holo_dark.png Binary files differnew file mode 100644 index 0000000..a8da981 --- /dev/null +++ b/core/res/res/drawable-hdpi/ic_ab_back_holo_dark.png diff --git a/core/res/res/drawable-hdpi/ic_ab_back_holo_light.png b/core/res/res/drawable-hdpi/ic_ab_back_holo_light.png Binary files differnew file mode 100644 index 0000000..af0f308 --- /dev/null +++ b/core/res/res/drawable-hdpi/ic_ab_back_holo_light.png diff --git a/core/res/res/drawable-mdpi/ic_ab_back_holo_dark.png b/core/res/res/drawable-mdpi/ic_ab_back_holo_dark.png Binary files differnew file mode 100644 index 0000000..7aae741 --- /dev/null +++ b/core/res/res/drawable-mdpi/ic_ab_back_holo_dark.png diff --git a/core/res/res/drawable-mdpi/ic_ab_back_holo_light.png b/core/res/res/drawable-mdpi/ic_ab_back_holo_light.png Binary files differnew file mode 100644 index 0000000..66ef51c --- /dev/null +++ b/core/res/res/drawable-mdpi/ic_ab_back_holo_light.png diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index f0d5fd8..0cac7eb 100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -4240,18 +4240,21 @@ <attr name="navigationMode"> <!-- Normal static title text --> <enum name="normal" value="0" /> - <!-- The action bar will use a drop-down selection in place of title text. --> - <enum name="dropdownList" value="1" /> - <!-- The action bar will use a series of horizontal tabs in place of title text. --> - <enum name="tabBar" value="2" /> + <!-- The action bar will use a selection list for navigation. --> + <enum name="listMode" value="1" /> + <!-- The action bar will use a series of horizontal tabs for navigation. --> + <enum name="tabMode" value="2" /> </attr> <!-- Options affecting how the action bar is displayed. --> <attr name="displayOptions"> - <flag name="useLogo" value="1" /> - <flag name="hideHome" value="2" /> + <flag name="useLogo" value="0x1" /> + <flag name="showHome" value="0x2" /> + <flag name="homeAsUp" value="0x4" /> + <flag name="showTitle" value="0x8" /> + <flag name="showCustom" value="0x10" /> + <!-- DEPRECATED - Remove this later!! --> + <flag name="hideHome" value="0x1000" /> </attr> - <!-- Specifies the color used to style the action bar. --> - <attr name="colorFilter" format="color" /> <!-- Specifies title text used for navigationMode="normal" --> <attr name="title" /> <!-- Specifies subtitle text used for navigationMode="normal" --> @@ -4272,6 +4275,8 @@ <attr name="customNavigationLayout" format="reference" /> <!-- Specifies a fixed height. --> <attr name="height" /> + <!-- Specifies a drawable to use for the 'home as up' indicator. --> + <attr name="homeAsUpIndicator" format="reference" /> </declare-styleable> <declare-styleable name="ActionMode"> @@ -4305,4 +4310,8 @@ <flag name="end" value="4" /> </attr> </declare-styleable> + + <declare-styleable name="ActionBar_LayoutParams"> + <attr name="layout_gravity" /> + </declare-styleable> </resources> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index bc20fbb..d704366 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1357,6 +1357,7 @@ <public type="attr" name="dividerVertical" /> <public type="attr" name="buttonGroupStyle" /> <public type="attr" name="alertDialogButtonGroupStyle" /> + <public type="attr" name="homeAsUpIndicator" /> <public type="anim" name="animator_fade_in" /> <public type="anim" name="animator_fade_out" /> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index df11c34..adf1715 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -911,7 +911,7 @@ <style name="Widget.ActionBar"> <item name="android:background">@android:drawable/action_bar_background</item> - <item name="android:displayOptions">useLogo</item> + <item name="android:displayOptions">useLogo|showHome|showTitle</item> <item name="android:divider">@android:drawable/action_bar_divider</item> <item name="android:height">?android:attr/actionBarSize</item> <item name="android:paddingLeft">0dip</item> @@ -1536,6 +1536,7 @@ <item name="android:subtitleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Subtitle</item> <item name="android:background">@null</item> <item name="android:divider">?android:attr/dividerVertical</item> + <item name="android:homeAsUpIndicator">@android:drawable/ic_ab_back_holo_dark</item> </style> <!-- Light widget styles --> @@ -1788,6 +1789,7 @@ <item name="android:titleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Title</item> <item name="android:subtitleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Subtitle</item> <item name="android:background">@null</item> + <item name="android:homeAsUpIndicator">@android:drawable/ic_ab_back_holo_light</item> </style> <!-- Animation Styles --> diff --git a/docs/html/sdk/adding-components.jd b/docs/html/sdk/adding-components.jd index 63c577e..755f200 100644 --- a/docs/html/sdk/adding-components.jd +++ b/docs/html/sdk/adding-components.jd @@ -6,7 +6,7 @@ page.title=Adding SDK Components <div id="qv"> <h2>Quickview</h2> <ul> - <li>Use the Android SDK and AVD Manager to + <li>Use the Android SDK and AVD Manager to set up your SDK and keep it up-to-date.</li> </ul> @@ -25,7 +25,7 @@ page.title=Adding SDK Components <p>Adding and updating components in your Android SDK is fast and easy. To perform an update, use the <strong>Android SDK and AVD Manager</strong> to install or update the individual SDK components that you need. The Android SDK -and AVD Manager tool is included in the <a href="index.html">Android SDK +and AVD Manager tool is included in the <a href="index.html">Android SDK download</a>.</p> <p>It only takes a couple of clicks to install individual versions of the @@ -53,19 +53,19 @@ a new version of the platform. See the revisions listed in the <a href="{@docRoot}sdk/tools-notes.html">SDK Tools</a> document for ADT Plugin compatibility.</p> -<div style="TEXT-ALIGN:left; width:600px;"> -<img src="{@docRoot}images/sdk_manager_packages.png" -style="padding-bottom:0;margin-bottom:0;" /> +<div style="TEXT-ALIGN:left; width:600px;"> +<img src="{@docRoot}images/sdk_manager_packages.png" +style="padding-bottom:0;margin-bottom:0;" /> <p class="caption" style="margin:0 0 1.5em 1em;padding:0 0 0 -1em;"><strong>Figure 1.</strong> The Android SDK and AVD Manager's +1em;"><strong>Figure 1.</strong> The Android SDK and AVD Manager's <strong>Available Packages</strong> panel, which shows the SDK components that are available for you to download into your environment. </p> -</div> +</div> <h2 id="launching">Launching the Android SDK and AVD Manager</h2> -<p>The Android SDK and AVD Manager is the tool that you use to install and +<p>The Android SDK and AVD Manager is the tool that you use to install and upgrade SDK components in your development environment. </p> <p>You can access the tool in any of three ways:</p> @@ -83,15 +83,15 @@ follow these steps to access the Android SDK and AVD Manager tool:</p> <ol> <li>Open Eclipse</li> -<li>Select <strong>Window</strong> > <strong>Android SDK and AVD +<li>Select <strong>Window</strong> > <strong>Android SDK and AVD Manager</strong>.</li> </ol> -<h4>Launching from the setup script (Windows only)</h4> +<h4>Launching from the SDK Manager script (Windows only)</h4> <p>For Windows only, the SDK includes a script that invokes the Android SDK and -AVD Manager. To launch the tool using the script, double-click "SDK -Setup.exe" at the root of the the SDK directory.</p> +AVD Manager. To launch the tool using the script, double-click {@code SDK +Manager.exe} at the root of the the SDK directory.</p> <h4>Launching from a command line</h4> @@ -100,37 +100,39 @@ and AVD Manager tool from the command line: </p> <ol> <li>Navigate to the <code><<em>sdk</em>>/tools/</code> directory.</li> -<li>Execute the {@code android} tool command with no options. +<li>Execute the {@code android} tool command with no options. <pre style="width:400px">$ android</pre></li> </ol> <h2 id="InstallingComponents">Installing SDK Components</h2> -<p class="caution"><strong>Important:</strong> Before you install SDK components, -we recommend that you disable any antivirus programs that may be running on -your computer.</p> +<p class="caution"><strong>Caution:</strong> Before you install SDK components, +we recommend that you disable any antivirus software that may be running on +your computer. There are cases in which antivirus software on Windows is known to interfere with the +installation process, so we suggest you disable your antivirus until installation is +complete.</p> <p>Follow these steps to install new SDK components in your environment:</p> <ol> <li>Launch the Android SDK and AVD Manager as described in the section above.</li> <li>Select <strong>Available Packages</strong> in the left panel. - This will reveal all of the components that are currently available for download + This will reveal all of the components that are currently available for download from the SDK repository.</li> <li>Select the component(s) you'd like to install and click <strong>Install - Selected</strong>. If you aren't sure which packages to select, read <a + Selected</strong>. If you aren't sure which packages to select, read <a href="installing.html#which">Which components do I need?</a>.</li> <li>Verify and accept the components you want and click <strong>Install Accepted</strong>. The components will now be installed into your existing Android SDK directories.</li> </ol> -<p>New platforms are automatically saved into the +<p>New platforms are automatically saved into the <code><<em>sdk</em>>/platforms/</code> directory of your SDK; new add-ons are saved in the <code><<em>sdk</em>>/add-ons/</code> -directory; samples are saved in the -<code><<em>sdk</em>>/samples/android-<<em>level</em>>/</code>; +directory; samples are saved in the +<code><<em>sdk</em>>/samples/android-<<em>level</em>>/</code>; and new documentation is saved in the existing <code><<em>sdk</em>>/docs/</code> directory (old docs are replaced).</p> @@ -184,10 +186,10 @@ if there is dependency that you need to address. </p> <h2 id="AddingSites">Adding New Sites</h2> <p>By default, <strong>Available Packages</strong> only shows the default -repository site, which offers platforms, SDK tools, documentation, the -Google APIs Add-on, and other components. You can add other sites that host +repository site, which offers platforms, SDK tools, documentation, the +Google APIs Add-on, and other components. You can add other sites that host their own Android SDK add-ons, then download the SDK add-ons -from those sites.</p> +from those sites.</p> <p>For example, a mobile carrier or device manufacturer might offer additional API libraries that are supported by their own Android-powered devices. In order @@ -199,7 +201,7 @@ Manager:</p> <ol> <li>Select <strong>Available Packages</strong> in the left panel.</li> - <li>Click <strong>Add Site</strong> and enter the URL of the + <li>Click <strong>Add Site</strong> and enter the URL of the {@code repository.xml} file. Click <strong>OK</strong>.</li> </ol> <p>Any SDK components available from the site will now be listed under diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd index 7016eee..2e59801 100644 --- a/docs/html/sdk/index.jd +++ b/docs/html/sdk/index.jd @@ -1,27 +1,27 @@ page.title=Android SDK sdk.redirect=0 -sdk.win_download=android-sdk_r07-windows.zip -sdk.win_bytes=23669664 -sdk.win_checksum=69c40c2d2e408b623156934f9ae574f0 +sdk.win_installer=installer_r08-windows.exe +sdk.win_installer_bytes=TODO +sdk.win_installer_checksum=TODO -sdk.mac_download=android-sdk_r07-mac_x86.zip -sdk.mac_bytes=19229546 -sdk.mac_checksum=0f330ed3ebb36786faf6dc72b8acf819 +sdk.win_download=android-sdk_r08-windows.zip +sdk.win_bytes=TODO +sdk.win_checksum=TODO -sdk.linux_download=android-sdk_r07-linux_x86.tgz -sdk.linux_bytes=17114517 -sdk.linux_checksum=e10c75da3d1aa147ddd4a5c58bfc3646 +sdk.mac_download=android-sdk_r08-mac_x86.zip +sdk.mac_bytes=TODO +sdk.mac_checksum=TODO + +sdk.linux_download=android-sdk_r08-linux_x86.tgz +sdk.linux_bytes=TODO +sdk.linux_checksum=TODO @jd:body <h2 id="quickstart">Quick Start</h2> -<p>The steps below provide an overview of how to get started with the Android -SDK. For detailed instructions, start with the <a -href="{@docRoot}sdk/installing.html">Installing the SDK</a> guide. </p> - <p><strong>1. Prepare your development computer</strong></p> <p>Read the <a href="{@docRoot}sdk/requirements.html">System Requirements</a> @@ -34,38 +34,37 @@ install the <a href="http://java.sun.com/javase/downloads/index.jsp">JDK</a> <p><strong>2. Download and install the SDK starter package</strong></p> -<p>Select a starter package from the table at the top of this page and download -it to your development computer. To install the SDK, simply unpack the starter -package to a safe location and then add the location to your PATH. </p> +<p>Download a starter package from the table above onto your development computer. +If you're using Windows, we recommend that you download the installer (the {@code .exe} file), +which will launch a Wizard to guide you through the installation and check your computer for +required software. Otherwise, download the SDK starter package ({@code .zip} or {@code .tgz}) +appropriate for your system, unpack it to a safe location, then add the location to your PATH +environment variable. </p> <p><strong>3. Install the ADT Plugin for Eclipse</strong></p> -<p>If you are developing in Eclipse, set up a remote update site at -<code>https://dl-ssl.google.com/android/eclipse/</code>. Install the Android -Development Tools (ADT) Plugin, restart Eclipse, and set the "Android" -preferences in Eclipse to point to the SDK install location. For detailed -instructions, see <a href="{@docRoot}sdk/eclipse-adt.html">ADT Plugin +<p>If you are developing in Eclipse, add a new remote update site with the URL +<code>https://dl-ssl.google.com/android/eclipse/</code>. Install the Android +Development Tools (ADT) Plugin from that site, restart Eclipse, and set the "Android" +preferences in Eclipse to point to the Android SDK directory (installed in the previous step). For +detailed instructions to setup Eclipse, see <a href="{@docRoot}sdk/eclipse-adt.html">ADT Plugin for Eclipse</a>.</p> <p><strong>4. Add Android platforms and other components to your SDK</strong></p> -<p>Use the Android SDK and AVD Manager, included in the SDK starter package, to -add one or more Android platforms (for example, Android 1.6 or Android 2.2) and -other components to your SDK. If you aren't sure what to add, see <a +<p>Launch the <em>Android SDK and AVD Manager</em> by executing {@code SDK Manager.exe} (Windows) or +{@code android} (Mac/Linux) from the SDK's {@code tools/} directory (if you used the Windows +installer, this is launched for you when the Wizard is complete). Add some Android platforms +(such as Android 1.6 and Android 2.3) and other components (such as documentation) to your SDK. If +you aren't sure what to add, see <a href="installing.html#which">Which components do I need?</a></p> -<p>To launch the Android SDK and AVD Manager on Windows, execute <code>SDK -Setup.exe</code>, at the root of the SDK directory. On Mac OS X or Linux, -execute the <code>android</code> tool in the <code><sdk>/tools/</code> -folder. For detailed instructions, see <a -href="{@docRoot}sdk/adding-components.html">Adding SDK Components</a>.</p> - <p><strong>Done!</strong></p> -<p>If you are new to Android, you can use the <a -href="{@docRoot}resources/tutorials/hello-world.html">Hello World</a> tutorial to -get started quickly. <a href="{@docRoot}sdk/installing.html#NextSteps">Next -Steps</a> offers other suggestions of how to begin.</p> +<p>To write your first Android application, see the <a +href="{@docRoot}resources/tutorials/hello-world.html">Hello World</a> tutorial. Also see <a +href="{@docRoot}sdk/installing.html#NextSteps">Next +Steps</a> for other suggestions about how to get started.</p> -<p>For a more detailed guide to installing and setting up the SDK, read <a +<p>For a more detailed guide to installing and setting up the SDK, read <a href="installing.html">Installing the SDK</a>.</p> diff --git a/docs/html/sdk/installing.jd b/docs/html/sdk/installing.jd index 73190a0..8484bea 100644 --- a/docs/html/sdk/installing.jd +++ b/docs/html/sdk/installing.jd @@ -29,20 +29,20 @@ sdk.preview=0 </div> </div> -<p>This page describes how to install the Android SDK +<p>This page describes how to install the Android SDK and set up your development environment for the first time.</p> -<p>If you encounter any problems during installation, see the +<p>If you encounter any problems during installation, see the <a href="#troubleshooting">Troubleshooting</a> section at the bottom of this page.</p> <h4>Updating?</h4> -<p>If you are currently using the Android 1.6 SDK or later and want to update -to the latest tools or platforms, you do not need to install a new SDK. Instead, -you can simply update the individual components in your SDK using the -Android SDK and AVD Manager tool. For information about how to do that, see <a -href="{@docRoot}sdk/adding-components.html#UpdatingComponents">Updating SDK +<p>If you are currently using the Android 1.6 SDK or later and want to update +to the latest tools or platforms, you do not need to install a new SDK. Instead, +you can simply update the individual components in your SDK using the +Android SDK and AVD Manager tool. For information about how to do that, see <a +href="{@docRoot}sdk/adding-components.html#UpdatingComponents">Updating SDK Components</a></p> <p>If you are using Android 1.5 SDK or earlier, you should install a new SDK as @@ -54,65 +54,71 @@ SDK environment. </p> <p>Before getting started with the Android SDK, take a moment to confirm that your development computer meets the <a href="requirements.html">System -Requirements</a>. In particular, you may need to install the <a -href="http://java.sun.com/javase/downloads/index.jsp">JDK</a> before +Requirements</a>. In particular, you may need to install the <a +href="http://java.sun.com/javase/downloads/index.jsp">JDK</a> before continuing, if it's not already installed on your computer. </p> <p>If you will be developing in Eclipse with the Android Development Tools (ADT) Plugin — the recommended path if you are new to Android — make sure that you have a suitable version of Eclipse -installed on your computer (3.4 or newer is recommended). If you need -to install Eclipse, you can download it from this location: </p> - +installed on your computer (3.4 or newer is recommended). If you need +to install Eclipse, you can download it from this location: </p> + <p style="margin-left:2em;"><a href= -"http://www.eclipse.org/downloads/">http://www.eclipse.org/downloads/</a></p> - -<p>A Java or RCP version of Eclipse is recommended. For Eclipse 3.5, the -"Eclipse Classic" version is recommended.</p> +"http://www.eclipse.org/downloads/">http://www.eclipse.org/downloads/</a></p> + +<p>A Java or RCP version of Eclipse is recommended. For Eclipse 3.5, the +"Eclipse Classic" version is recommended.</p> <h2 id="Installing">Step 2. Downloading the SDK Starter Package</h2> <p>The first step in setting up your environment for developing Android applications is downloading the Android SDK starter package. The starter package is not a full -development environment — it includes only the core SDK Tools, which you can -use to download the rest of the SDK components. </p> +development environment — it includes only the core SDK Tools, which you can +use to download the rest of the SDK components (such as the platform system images). </p> <p>You can get the latest version of the SDK starter package from the <a href="{@docRoot}sdk/index.html">SDK download page</a>. Make sure to download the package that is appropriate for your development computer.</p> -<p>After downloading, unpack the Android SDK archive to a safe location on your -machine. By default, the SDK files are unpacked into a directory named -<code>android-sdk-<machine-platform></code>. Make a note of the name and +<p class="note"><strong>Note:</strong> If you're using Windows, we recommend that you download +the SDK installer (the {@code .exe} file from the download table). It will guide you through the +installation process and check your computer for the required software.</p> + +<p>If you downloaded a {@code .zip} of {@code .tgz} (instead of using the SDK installer), unpack the +Android SDK archive to a safe location on your machine. By default, the SDK files are unpacked into +a directory named <code>android-sdk-<machine-platform></code>.</p> + +<p>Make a note of the name and location of the unpacked SDK directory on your system — you will need to -refer to the SDK directory later, when setting up the ADT plugin or when using -the SDK tools.</p> - -<p>Optionally, you may want to add the location of the SDK's primary -<code>tools</code> directory to your system <code>PATH</code>. The primary -<code>tools/</code> directory is located at the root of the SDK folder. Adding -<code>tools</code> to your path lets you run Android Debug Bridge (adb) and the -other command line <a +refer to the SDK directory later, when setting up the ADT plugin and when using +the SDK tools from command line.</p> + +<p>Optionally, you might want to add the location of the SDK's primary +<code>tools</code> directory and the additional {@code platform-tools/} directory to your system +<code>PATH</code>. Both tool directories are located at the root of the SDK folder. Adding +<code>tools/</code> and {@code platform-tools/} to your path lets you run Android Debug Bridge (adb) +and the other command line <a href="{@docRoot}guide/developing/tools/index.html">tools</a> without needing to -supply the full path to the tools directory. </p> +supply the full path to the tool directories. </p> <ul> <li>On Linux, edit your <code>~/.bash_profile</code> or <code>~/.bashrc</code> file. Look for a line that sets the PATH environment variable and add the - full path to the <code>tools/</code> directory to it. If you don't + full path to the <code>tools/</code> and {@code platform-tools/} directories to it. If you don't see a line setting the path, you can add one:</li> - <ul><code>export PATH=${PATH}:<em><your_sdk_dir></em>/tools</code></ul> + <ul><code>export PATH=${PATH}:<your_sdk_dir>/tools:<your_sdk_dir>/platform-tools</code></ul> <li>On a Mac OS X, look in your home directory for <code>.bash_profile</code> and - proceed as for Linux. You can create the <code>.bash_profile</code> if + proceed as for Linux. You can create the <code>.bash_profile</code> if you haven't already set one up on your machine. </li> - <li>On Windows, right-click on My Computer, and select Properties. + <li>On Windows, right-click on My Computer, and select Properties. Under the Advanced tab, hit the Environment Variables button, and in the - dialog that comes up, double-click on Path (under System Variables). Add the full path to the - <code>tools/</code> directory to the path. </li> + dialog that comes up, double-click on Path (under System Variables). Add the full path to the + <code>tools/</code> and {@code platform-tools/} directories to the path. </li> </ul> <p>If you will be using the Eclipse IDE as your development environment, the @@ -203,11 +209,11 @@ access to powerful mapping capabilities through the <code>com.google.android.maps</code> library. You can also add additional repositories, so that you can download other SDK add-ons, where available. </li> -<li><strong>USB Driver for Windows</strong> — Contains driver files +<li><strong>USB Driver for Windows</strong> — Contains driver files that you can install on your Windows computer, so that you can run and debug your applications on an actual device. You <em>do not</em> need the USB driver unless you plan to debug your application on an actual Android-powered device. If you -develop on Mac OS X or Linux, you do not need a special driver to debug +develop on Mac OS X or Linux, you do not need a special driver to debug your application on an Android-powered device.</li> <li><strong>Samples</strong> — Contains the sample code and apps available @@ -226,15 +232,15 @@ Manager, shown in Figure 1, to browse the SDK repository, select new or updated components for download, and then install the selected components in your SDK environment. </p> -<div style="TEXT-ALIGN:left;width:600px;"> -<img src="/images/sdk_manager_packages.png" -style="padding-bottom:0;margin-bottom:0;" /> +<div style="TEXT-ALIGN:left;width:600px;"> +<img src="/images/sdk_manager_packages.png" +style="padding-bottom:0;margin-bottom:0;" /> <p class="caption" style="margin:0 0 1.5em 1em;padding:0 0 0 -1em;"><strong>Figure 1.</strong> The Android SDK and AVD Manager's +1em;"><strong>Figure 1.</strong> The Android SDK and AVD Manager's <strong>Available Packages</strong> panel, which shows the SDK components that are available for you to download into your environment. </p> -</div> +</div> <h3 id="which">Which components do I need?</h3> @@ -257,8 +263,8 @@ recommended or full development environment: </p> <td style="font-size:.9em;background-color:#FFE;color:gray">SDK Tools</td> <td style="font-size:.9em;background-color:#FFE;color:gray">If you've installed the SDK starter package, then you already have this component preinstalled. The -SDK Tools component is required — you can't develop or build an application -without it. </td> +SDK Tools and the SDK Platform-tools components are required — you can't develop or build an +application without these. Make sure you keep these up to date.</td> </tr> <tr> @@ -324,8 +330,8 @@ applications on different platforms by running in an Android Virtual Device to add components, see the <a href="{@docRoot}sdk/adding-components.html">Adding SDK Components</a> document. </p> -<p>For revision notes and other detailed information about individual SDK -components, see the documents listed under "Downloadable SDK Components" in +<p>For revision notes and other detailed information about individual SDK +components, see the documents listed under "Downloadable SDK Components" in the navigation at left.</p> @@ -335,7 +341,7 @@ the navigation at left.</p> and add-ons that you need, open the SDK directory and take a look at what's inside.</p> -<p>The table below describes the full SDK directory contents, with components +<p>The table below describes the full SDK directory contents, with components installed. </p> <table> @@ -351,10 +357,19 @@ devices. </td> <tr> <td colspan="3"><code>docs/</code></td> <td>A full set of documentation in HTML format, including the Developer's Guide, -API Reference, and other information. To read the documentation, load the +API Reference, and other information. To read the documentation, load the file <code>offline.html</code> in a web browser.</td> </tr> <tr> +<td colspan="3"><code>platform-tools/</code></td> +<td>Contains development tools that may be updated with each platform release (from the <em>Android +SDK Platform-tools</em> component). Tools in here include {@code adb}, {@code dexdump}, and others +others that you don't typically use directly. These tools are separate from the generic development +tools in the {@code tools/} directory, because these tools may be updated in order to support new +features in the latest Android platform, whereas the other tools have no dependencies on the +platform version.</td> +</tr> +<tr> <td colspan="3"><code>platforms/</code></td> <td>Contains a set of Android platform versions that you can develop applications against, each in a separate directory. </td> @@ -362,7 +377,7 @@ applications against, each in a separate directory. </td> <tr> <td style="width:2em;border-bottom-color:white;"></td> <td colspan="2"><code><em><platform></em>/</code></td> -<td>Platform version directory, for example "android-1.6". All platform version +<td>Platform version directory, for example "android-1.6". All platform version directories contain a similar set of files and subdirectory structure.</td> </tr> @@ -376,8 +391,8 @@ directories contain a similar set of files and subdirectory structure.</td> <td style="width:2em;border-bottom-color:white;"></td> <td style="width:2em;border-bottom-color:white;"></td> <td><code>images/</code></td> -<td>Storage area for default disk images, including the Android system image, -the default userdata image, the default ramdisk image, and more. The images +<td>Storage area for default disk images, including the Android system image, +the default userdata image, the default ramdisk image, and more. The images are used in emulator sessions.</td> </tr> <tr> @@ -397,7 +412,8 @@ designed for a specific screen resolution.</td> <td style="width:2em;border-bottom-color:white;"></td> <td style="width:2em;border-bottom-color:white;"></td> <td><code>tools/</code></td> -<td>Any development tools that are specific to the platform version.</td> +<td>This directory is used only by SDK Tools r7 and below for development tools that are specific to +this platform version—it's not used by SDK Tools r8 and above.</td> </tr> <tr> <td style="width:2em;"></td> @@ -411,18 +427,21 @@ version.</td> <td>Sample code and apps that are specific to platform version.</td> </tr> <td colspan="3"><code>tools/</code></td> -<td>Contains the set of development and profiling tools available to you, such -as the emulator, the <code>android</code> tool, adb, ddms, and more.</td> +<td>Contains the set of development and profiling tools that are platform-independent, such +as the emulator, the AVD and SDK Manager, adb, ddms, hierarchyviewer and more. The tools in +this directory may be updated at any time (from the <em>Android SDK Tools</em> component), +independent of platform releases, whereas the tools in {@code platform-tools/} may be updated based +on the latest platform release.</td> </tr> <tr> <td colspan="3"><code>SDK Readme.txt</code></td> -<td>A file that explains how to perform the initial setup of your SDK, -including how to launch the Android SDK and AVD Manager tool on all +<td>A file that explains how to perform the initial setup of your SDK, +including how to launch the Android SDK and AVD Manager tool on all platforms</td> </tr> <tr> -<td colspan="3"><code>SDK Setup.exe</code></td> -<td>Windows SDK only. A shortcut that launches the Android SDK and AVD +<td colspan="3"><code>SDK Manager.exe</code></td> +<td>Windows SDK only. A shortcut that launches the Android SDK and AVD Manager tool, which you use to add components to your SDK. </td> </tr> <!--<tr> @@ -447,7 +466,7 @@ begin developing applications. Here are a few ways you can get started: </p> </li> </ul> -<p class="caution">Following the Hello World tutorial is an essential +<p class="caution">Following the Hello World tutorial is an essential first step in getting started with Android development. </p> <p><strong>Learn about Android</strong></p> @@ -481,20 +500,20 @@ Android-powered device to run and test your application.</li> <ul> <li>The <a href="{@docRoot}resources/tutorials/notepad/index.html"> - Notepad Tutorial</a> shows you how to build a full Android application - and provides helpful commentary on the Android system and API. The + Notepad Tutorial</a> shows you how to build a full Android application + and provides helpful commentary on the Android system and API. The Notepad tutorial helps you bring together the important design - and architectural concepts in a moderately complex application. + and architectural concepts in a moderately complex application. </li> </ul> -<p class="caution">Following the Notepad tutorial is an excellent +<p class="caution">Following the Notepad tutorial is an excellent second step in getting started with Android development. </p> <p><strong>Explore some code</strong></p> <ul> <li>The Android SDK includes sample code and applications for each platform -version. You can browse the samples in the <a +version. You can browse the samples in the <a href="{@docRoot}resources/index.html">Resources</a> tab or download them into your SDK using the Android SDK and AVD Manager. Once you've downloaded the samples, you'll find them in @@ -517,7 +536,7 @@ samples, you'll find them in <ul> <li>If you need help installing and configuring Java on your - development machine, you might find these resources helpful: + development machine, you might find these resources helpful: <ul> <li><a href="https://help.ubuntu.com/community/Java">https://help.ubuntu.com/community/Java </a></li> <li><a href="https://help.ubuntu.com/community/Java">https://help.ubuntu.com/community/JavaInstallation</a></li> @@ -537,7 +556,7 @@ samples, you'll find them in eclipse.org (<a href="http://www.eclipse.org/downloads/">http://www.eclipse.org/ downloads/</a>). A Java or RCP version of Eclipse is recommended.</li> - <li>Follow the steps given in previous sections to install the SDK + <li>Follow the steps given in previous sections to install the SDK and the ADT plugin. </li> </ol> </li> diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index cf04e92..60a41bf 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -1192,6 +1192,13 @@ void AwesomePlayer::finishSeekIfNecessary(int64_t videoTimeUs) { mFlags |= FIRST_FRAME; mSeeking = false; mSeekNotificationSent = false; + + if (mDecryptHandle != NULL) { + mDrmManagerClient->setPlaybackStatus(mDecryptHandle, + Playback::PAUSE, 0); + mDrmManagerClient->setPlaybackStatus(mDecryptHandle, + Playback::START, videoTimeUs / 1000); + } } void AwesomePlayer::onVideoEvent() { @@ -1295,13 +1302,6 @@ void AwesomePlayer::onVideoEvent() { TimeSource *ts = (mFlags & AUDIO_AT_EOS) ? &mSystemTimeSource : mTimeSource; - if (mDecryptHandle != NULL) { - mDrmManagerClient->setPlaybackStatus(mDecryptHandle, - Playback::PAUSE, 0); - mDrmManagerClient->setPlaybackStatus(mDecryptHandle, - Playback::START, timeUs / 1000); - } - if (mFlags & FIRST_FRAME) { mFlags &= ~FIRST_FRAME; diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp index ea5577d..0b8997c 100644 --- a/media/libstagefright/DataSource.cpp +++ b/media/libstagefright/DataSource.cpp @@ -32,6 +32,8 @@ #include <media/stagefright/MediaErrors.h> #include <utils/String8.h> +#include <cutils/properties.h> + namespace android { bool DataSource::getUInt16(off_t offset, uint16_t *x) { @@ -105,7 +107,12 @@ void DataSource::RegisterDefaultSniffers() { RegisterSniffer(SniffAMR); RegisterSniffer(SniffMPEG2TS); RegisterSniffer(SniffMP3); - //RegisterSniffer(SniffDRM); + + char value[PROPERTY_VALUE_MAX]; + if (property_get("drm.service.enabled", value, NULL) + && (!strcmp(value, "1") || !strcasecmp(value, "true"))) { + RegisterSniffer(SniffDRM); + } } // static |
