diff options
author | Adam Powell <adamp@google.com> | 2013-04-05 16:27:35 -0700 |
---|---|---|
committer | Adam Powell <adamp@google.com> | 2013-04-05 16:46:22 -0700 |
commit | e0e2f4fd3ac8e70e341ae52d6376d8d67bd9edce (patch) | |
tree | 00107e2b778cfad5781b95190b6c3dd4b13e3ed0 | |
parent | bdc87d50db42999fbfeb0d75a98d1cb0e3730bc0 (diff) | |
download | frameworks_base-e0e2f4fd3ac8e70e341ae52d6376d8d67bd9edce.zip frameworks_base-e0e2f4fd3ac8e70e341ae52d6376d8d67bd9edce.tar.gz frameworks_base-e0e2f4fd3ac8e70e341ae52d6376d8d67bd9edce.tar.bz2 |
Fix accessibility in action bars and add extra customization
Fix a bug where the content description of the big unified Home/Up
button was not getting set properly.
Add the ability to change the home-as-up glyph from ActionBar.
Add the ability to set a custom action description for the home-as-up
button, useful if the above functionality is used.
Bug 8548229
Change-Id: I0635799772c7234b68247dfc105dce7f11acda32
-rw-r--r-- | api/current.txt | 4 | ||||
-rw-r--r-- | core/java/android/app/ActionBar.java | 80 | ||||
-rw-r--r-- | core/java/com/android/internal/app/ActionBarImpl.java | 20 | ||||
-rw-r--r-- | core/java/com/android/internal/view/menu/ActionMenuItem.java | 2 | ||||
-rw-r--r-- | core/java/com/android/internal/widget/ActionBarView.java | 86 | ||||
-rw-r--r-- | core/res/res/values/strings.xml | 11 | ||||
-rw-r--r-- | core/res/res/values/symbols.xml | 2 |
7 files changed, 198 insertions, 7 deletions
diff --git a/api/current.txt b/api/current.txt index d7da071..a0708bb 100644 --- a/api/current.txt +++ b/api/current.txt @@ -2595,6 +2595,10 @@ package android.app { method public abstract void setDisplayShowHomeEnabled(boolean); method public abstract void setDisplayShowTitleEnabled(boolean); method public abstract void setDisplayUseLogoEnabled(boolean); + method public void setHomeActionContentDescription(java.lang.CharSequence); + method public void setHomeActionContentDescription(int); + method public void setHomeAsUpIndicator(android.graphics.drawable.Drawable); + method public void setHomeAsUpIndicator(int); method public void setHomeButtonEnabled(boolean); method public abstract void setIcon(int); method public abstract void setIcon(android.graphics.drawable.Drawable); diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java index 3602fc4..c4ddf1f 100644 --- a/core/java/android/app/ActionBar.java +++ b/core/java/android/app/ActionBar.java @@ -695,6 +695,86 @@ public abstract class ActionBar { public boolean isTitleTruncated() { return false; } /** + * Set an alternate drawable to display next to the icon/logo/title + * when {@link #DISPLAY_HOME_AS_UP} is enabled. This can be useful if you are using + * this mode to display an alternate selection for up navigation, such as a sliding drawer. + * + * <p>If you pass <code>null</code> to this method, the default drawable from the theme + * will be used.</p> + * + * <p>If you implement alternate or intermediate behavior around Up, you should also + * call {@link #setHomeActionContentDescription(int) setHomeActionContentDescription()} + * to provide a correct description of the action for accessibility support.</p> + * + * @param indicator A drawable to use for the up indicator, or null to use the theme's default + * + * @see #setDisplayOptions(int, int) + * @see #setDisplayHomeAsUpEnabled(boolean) + * @see #setHomeActionContentDescription(int) + */ + public void setHomeAsUpIndicator(Drawable indicator) { } + + /** + * Set an alternate drawable to display next to the icon/logo/title + * when {@link #DISPLAY_HOME_AS_UP} is enabled. This can be useful if you are using + * this mode to display an alternate selection for up navigation, such as a sliding drawer. + * + * <p>If you pass <code>0</code> to this method, the default drawable from the theme + * will be used.</p> + * + * <p>If you implement alternate or intermediate behavior around Up, you should also + * call {@link #setHomeActionContentDescription(int) setHomeActionContentDescription()} + * to provide a correct description of the action for accessibility support.</p> + * + * @param resId Resource ID of a drawable to use for the up indicator, or null + * to use the theme's default + * + * @see #setDisplayOptions(int, int) + * @see #setDisplayHomeAsUpEnabled(boolean) + * @see #setHomeActionContentDescription(int) + */ + public void setHomeAsUpIndicator(int resId) { } + + /** + * Set an alternate description for the Home/Up action, when enabled. + * + * <p>This description is commonly used for accessibility/screen readers when + * the Home action is enabled. (See {@link #setDisplayHomeAsUpEnabled(boolean)}.) + * Examples of this are, "Navigate Home" or "Navigate Up" depending on the + * {@link #DISPLAY_HOME_AS_UP} display option. If you have changed the home-as-up + * indicator using {@link #setHomeAsUpIndicator(int)} to indicate more specific + * functionality such as a sliding drawer, you should also set this to accurately + * describe the action.</p> + * + * <p>Setting this to <code>null</code> will use the system default description.</p> + * + * @param description New description for the Home action when enabled + * @see #setHomeAsUpIndicator(int) + * @see #setHomeAsUpIndicator(android.graphics.drawable.Drawable) + */ + public void setHomeActionContentDescription(CharSequence description) { } + + /** + * Set an alternate description for the Home/Up action, when enabled. + * + * <p>This description is commonly used for accessibility/screen readers when + * the Home action is enabled. (See {@link #setDisplayHomeAsUpEnabled(boolean)}.) + * Examples of this are, "Navigate Home" or "Navigate Up" depending on the + * {@link #DISPLAY_HOME_AS_UP} display option. If you have changed the home-as-up + * indicator using {@link #setHomeAsUpIndicator(int)} to indicate more specific + * functionality such as a sliding drawer, you should also set this to accurately + * describe the action.</p> + * + * <p>Setting this to <code>0</code> will use the system default description.</p> + * + * @param resId Resource ID of a string to use as the new description + * for the Home action when enabled + * @see #setHomeAsUpIndicator(int) + * @see #setHomeAsUpIndicator(android.graphics.drawable.Drawable) + */ + public void setHomeActionContentDescription(int resId) { } + + /** * Listener interface for ActionBar navigation events. */ public interface OnNavigationListener { diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java index db20549..acbb2b1 100644 --- a/core/java/com/android/internal/app/ActionBarImpl.java +++ b/core/java/com/android/internal/app/ActionBarImpl.java @@ -812,6 +812,26 @@ public class ActionBarImpl extends ActionBar { return mActionView != null && mActionView.isTitleTruncated(); } + @Override + public void setHomeAsUpIndicator(Drawable indicator) { + mActionView.setHomeAsUpIndicator(indicator); + } + + @Override + public void setHomeAsUpIndicator(int resId) { + mActionView.setHomeAsUpIndicator(resId); + } + + @Override + public void setHomeActionContentDescription(CharSequence description) { + mActionView.setHomeActionContentDescription(description); + } + + @Override + public void setHomeActionContentDescription(int resId) { + mActionView.setHomeActionContentDescription(resId); + } + /** * @hide */ diff --git a/core/java/com/android/internal/view/menu/ActionMenuItem.java b/core/java/com/android/internal/view/menu/ActionMenuItem.java index 2685046..7ca6c1b 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuItem.java +++ b/core/java/com/android/internal/view/menu/ActionMenuItem.java @@ -107,7 +107,7 @@ public class ActionMenuItem implements MenuItem { } public CharSequence getTitleCondensed() { - return mTitleCondensed; + return mTitleCondensed != null ? mTitleCondensed : mTitle; } public boolean hasSubMenu() { diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java index b99b39a..59ff597 100644 --- a/core/java/com/android/internal/widget/ActionBarView.java +++ b/core/java/com/android/internal/widget/ActionBarView.java @@ -93,6 +93,8 @@ public class ActionBarView extends AbsActionBarView { private CharSequence mSubtitle; private Drawable mIcon; private Drawable mLogo; + private CharSequence mHomeDescription; + private int mHomeDescriptionRes; private HomeView mHomeLayout; private HomeView mExpandedHomeLayout; @@ -288,6 +290,10 @@ public class ActionBarView extends AbsActionBarView { initTitle(); } + if (mHomeDescriptionRes != 0) { + setHomeActionContentDescription(mHomeDescriptionRes); + } + if (mTabScrollView != null && mIncludeTabs) { ViewGroup.LayoutParams lp = mTabScrollView.getLayoutParams(); if (lp != null) { @@ -589,14 +595,43 @@ public class ActionBarView extends AbsActionBarView { mUpGoerFive.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO); } else { mUpGoerFive.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_AUTO); + mUpGoerFive.setContentDescription(buildHomeContentDescription()); + } + } + + /** + * Compose a content description for the Home/Up affordance. + * + * <p>As this encompasses the icon/logo, title and subtitle all in one, we need + * a description for the whole wad of stuff that can be localized properly.</p> + */ + private CharSequence buildHomeContentDescription() { + final CharSequence homeDesc; + if (mHomeDescription != null) { + homeDesc = mHomeDescription; + } else { if ((mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0) { - mUpGoerFive.setContentDescription(mContext.getResources().getText( - R.string.action_bar_up_description)); + homeDesc = mContext.getResources().getText(R.string.action_bar_up_description); } else { - mUpGoerFive.setContentDescription(mContext.getResources().getText( - R.string.action_bar_home_description)); + homeDesc = mContext.getResources().getText(R.string.action_bar_home_description); + } + } + + final CharSequence title = getTitle(); + final CharSequence subtitle = getSubtitle(); + if (!TextUtils.isEmpty(title)) { + final String result; + if (!TextUtils.isEmpty(subtitle)) { + result = getResources().getString( + R.string.action_bar_home_subtitle_description_format, + title, subtitle, homeDesc); + } else { + result = getResources().getString(R.string.action_bar_home_description_format, + title, homeDesc); } + return result; } + return homeDesc; } public void setDisplayOptions(int options) { @@ -1305,6 +1340,23 @@ public class ActionBarView extends AbsActionBarView { } } + public void setHomeAsUpIndicator(Drawable indicator) { + mHomeLayout.setUpIndicator(indicator); + } + + public void setHomeAsUpIndicator(int resId) { + mHomeLayout.setUpIndicator(resId); + } + + public void setHomeActionContentDescription(CharSequence description) { + mHomeDescription = description; + } + + public void setHomeActionContentDescription(int resId) { + mHomeDescriptionRes = resId; + mHomeDescription = getResources().getText(resId); + } + static class SavedState extends BaseSavedState { int expandedMenuItemId; boolean isOverflowOpen; @@ -1339,9 +1391,11 @@ public class ActionBarView extends AbsActionBarView { } private static class HomeView extends FrameLayout { - private View mUpView; + private ImageView mUpView; private ImageView mIconView; private int mUpWidth; + private int mUpIndicatorRes; + private Drawable mDefaultUpIndicator; private static final long DEFAULT_TRANSITION_DURATION = 150; @@ -1366,6 +1420,25 @@ public class ActionBarView extends AbsActionBarView { mIconView.setImageDrawable(icon); } + public void setUpIndicator(Drawable d) { + mUpView.setImageDrawable(d != null ? d : mDefaultUpIndicator); + mUpIndicatorRes = 0; + } + + public void setUpIndicator(int resId) { + mUpIndicatorRes = resId; + mUpView.setImageDrawable(resId != 0 ? getResources().getDrawable(resId) : null); + } + + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + if (mUpIndicatorRes != 0) { + // Reload for config change + setUpIndicator(mUpIndicatorRes); + } + } + @Override public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { onPopulateAccessibilityEvent(event); @@ -1389,8 +1462,9 @@ public class ActionBarView extends AbsActionBarView { @Override protected void onFinishInflate() { - mUpView = findViewById(com.android.internal.R.id.up); + mUpView = (ImageView) findViewById(com.android.internal.R.id.up); mIconView = (ImageView) findViewById(com.android.internal.R.id.home); + mDefaultUpIndicator = mUpView.getDrawable(); } public int getStartOffset() { diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 6bf6403..4e3ecbd 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -3771,6 +3771,17 @@ <string name="action_bar_up_description">Navigate up</string> <!-- Content description for the action menu overflow button. [CHAR LIMIT=NONE] --> <string name="action_menu_overflow_description">More options</string> + <!-- Formatting string for describing the action bar's title/home/up affordance. + This is a single tappable "button" that includes the app icon, the Up indicator + (usually a "<" chevron) and the window title text. + %1$s is the title. %2$s is the description of what tapping/clicking the whole + thing is going to do. --> + <string name="action_bar_home_description_format">%1$s, %2$s</string> + <!-- Just like action_bar_home_description_format, but this one will be used + if the window is also providing subtitle text. + %1$s is the title. %2$s is the subtitle. %3$s is the description of what + tapping/clicking the whole thing is going to do. --> + <string name="action_bar_home_subtitle_description_format">%1$s, %2$s, %3$s</string> <!-- Storage description for internal storage. [CHAR LIMIT=NONE] --> <string name="storage_internal">Internal storage</string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index bb35bab..8a7ecf5 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -870,6 +870,8 @@ <java-symbol type="string" name="config_chooseTypeAndAccountActivity" /> <java-symbol type="string" name="config_appsAuthorizedForSharedAccounts" /> <java-symbol type="string" name="error_message_title" /> + <java-symbol type="string" name="action_bar_home_description_format" /> + <java-symbol type="string" name="action_bar_home_subtitle_description_format" /> <java-symbol type="plurals" name="abbrev_in_num_days" /> <java-symbol type="plurals" name="abbrev_in_num_hours" /> |