diff options
author | Adam Powell <adamp@google.com> | 2015-01-13 19:01:19 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-01-13 19:01:19 +0000 |
commit | 57744dd139f3d30ed1031319dd64b289a68ac3ba (patch) | |
tree | 1f4dc4a0f7c30514436df8f922ed0d22b443ab2e | |
parent | b1a0a57ccab94e479087b620dcea2b39225693bb (diff) | |
parent | 69c22e82e9c3e95f4689a57320de3199ffd29262 (diff) | |
download | frameworks_base-57744dd139f3d30ed1031319dd64b289a68ac3ba.zip frameworks_base-57744dd139f3d30ed1031319dd64b289a68ac3ba.tar.gz frameworks_base-57744dd139f3d30ed1031319dd64b289a68ac3ba.tar.bz2 |
am 69c22e82: Merge "Add API for nested pre-processing of a11y events; fix ResolverDrawerLayout" into lmp-mr1-dev
* commit '69c22e82e9c3e95f4689a57320de3199ffd29262':
Add API for nested pre-processing of a11y events; fix ResolverDrawerLayout
-rw-r--r-- | api/current.txt | 3 | ||||
-rw-r--r-- | core/java/android/view/View.java | 41 | ||||
-rw-r--r-- | core/java/android/view/ViewGroup.java | 17 | ||||
-rw-r--r-- | core/java/android/view/ViewParent.java | 20 | ||||
-rw-r--r-- | core/java/android/view/ViewRootImpl.java | 5 | ||||
-rw-r--r-- | core/java/com/android/internal/widget/ResolverDrawerLayout.java | 59 |
6 files changed, 145 insertions, 0 deletions
diff --git a/api/current.txt b/api/current.txt index 24501f3..96c50a2 100644 --- a/api/current.txt +++ b/api/current.txt @@ -33332,6 +33332,7 @@ package android.view { method public boolean dispatchKeyShortcutEvent(android.view.KeyEvent); method public boolean dispatchNestedFling(float, float, boolean); method public boolean dispatchNestedPreFling(float, float); + method public boolean dispatchNestedPrePerformAccessibilityAction(int, android.os.Bundle); method public boolean dispatchNestedPreScroll(int, int, int[], int[]); method public boolean dispatchNestedScroll(int, int, int, int, int[]); method public boolean dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent); @@ -34144,6 +34145,7 @@ package android.view { method protected abstract void onLayout(boolean, int, int, int, int); method public boolean onNestedFling(android.view.View, float, float, boolean); method public boolean onNestedPreFling(android.view.View, float, float); + method public boolean onNestedPrePerformAccessibilityAction(android.view.View, int, android.os.Bundle); method public void onNestedPreScroll(android.view.View, int, int, int[]); method public void onNestedScroll(android.view.View, int, int, int, int); method public void onNestedScrollAccepted(android.view.View, android.view.View, int); @@ -34292,6 +34294,7 @@ package android.view { method public abstract void notifySubtreeAccessibilityStateChanged(android.view.View, android.view.View, int); method public abstract boolean onNestedFling(android.view.View, float, float, boolean); method public abstract boolean onNestedPreFling(android.view.View, float, float); + method public abstract boolean onNestedPrePerformAccessibilityAction(android.view.View, int, android.os.Bundle); method public abstract void onNestedPreScroll(android.view.View, int, int, int[]); method public abstract void onNestedScroll(android.view.View, int, int, int, int); method public abstract void onNestedScrollAccepted(android.view.View, android.view.View, int); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 23792be..6a36c26 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -8159,6 +8159,34 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * Report an accessibility action to this view's parents for delegated processing. + * + * <p>Implementations of {@link #performAccessibilityAction(int, Bundle)} may internally + * call this method to delegate an accessibility action to a supporting parent. If the parent + * returns true from its + * {@link ViewParent#onNestedPrePerformAccessibilityAction(View, int, android.os.Bundle)} + * method this method will return true to signify that the action was consumed.</p> + * + * <p>This method is useful for implementing nested scrolling child views. If + * {@link #isNestedScrollingEnabled()} returns true and the action is a scrolling action + * a custom view implementation may invoke this method to allow a parent to consume the + * scroll first. If this method returns true the custom view should skip its own scrolling + * behavior.</p> + * + * @param action Accessibility action to delegate + * @param arguments Optional action arguments + * @return true if the action was consumed by a parent + */ + public boolean dispatchNestedPrePerformAccessibilityAction(int action, Bundle arguments) { + for (ViewParent p = getParent(); p != null; p = p.getParent()) { + if (p.onNestedPrePerformAccessibilityAction(this, action, arguments)) { + return true; + } + } + return false; + } + + /** * Performs the specified accessibility action on the view. For * possible accessibility actions look at {@link AccessibilityNodeInfo}. * <p> @@ -8168,6 +8196,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * is responsible for handling this call. * </p> * + * <p>The default implementation will delegate + * {@link AccessibilityNodeInfo#ACTION_SCROLL_BACKWARD} and + * {@link AccessibilityNodeInfo#ACTION_SCROLL_FORWARD} to nested scrolling parents if + * {@link #isNestedScrollingEnabled() nested scrolling is enabled} on this view.</p> + * * @param action The action to perform. * @param arguments Optional action arguments. * @return Whether the action was performed. @@ -8188,6 +8221,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide Until we've refactored all accessibility delegation methods. */ public boolean performAccessibilityActionInternal(int action, Bundle arguments) { + if (isNestedScrollingEnabled() + && (action == AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD + || action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)) { + if (dispatchNestedPrePerformAccessibilityAction(action, arguments)) { + return true; + } + } + switch (action) { case AccessibilityNodeInfo.ACTION_CLICK: { if (isClickable()) { diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 22c5185..6678ff2 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -32,6 +32,7 @@ import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; import android.os.Build; +import android.os.Bundle; import android.os.Parcelable; import android.os.SystemClock; import android.util.AttributeSet; @@ -2923,6 +2924,22 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager /** * {@inheritDoc} + * + * <p>Subclasses should always call <code>super.onNestedPrePerformAccessibilityAction</code></p> + * + * @param target The target view dispatching this action + * @param action Action being performed; see + * {@link android.view.accessibility.AccessibilityNodeInfo} + * @param args Optional action arguments + * @return false by default. Subclasses should return true if they handle the event. + */ + @Override + public boolean onNestedPrePerformAccessibilityAction(View target, int action, Bundle args) { + return false; + } + + /** + * {@inheritDoc} */ @Override void dispatchDetachedFromWindow() { diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java index 87a37f4..035871d 100644 --- a/core/java/android/view/ViewParent.java +++ b/core/java/android/view/ViewParent.java @@ -17,6 +17,7 @@ package android.view; import android.graphics.Rect; +import android.os.Bundle; import android.view.accessibility.AccessibilityEvent; /** @@ -551,4 +552,23 @@ public interface ViewParent { * @return true if this parent consumed the fling ahead of the target view */ public boolean onNestedPreFling(View target, float velocityX, float velocityY); + + /** + * React to an accessibility action delegated by a target descendant view before the target + * processes it. + * + * <p>This method may be called by a target descendant view if the target wishes to give + * a view in its parent chain a chance to react to the event before normal processing occurs. + * Most commonly this will be a scroll event such as + * {@link android.view.accessibility.AccessibilityNodeInfo#ACTION_SCROLL_FORWARD}. + * A ViewParent that supports acting as a nested scrolling parent should override this + * method and act accordingly to implement scrolling via accesibility systems.</p> + * + * @param target The target view dispatching this action + * @param action Action being performed; see + * {@link android.view.accessibility.AccessibilityNodeInfo} + * @param arguments Optional action arguments + * @return true if the action was consumed by this ViewParent + */ + public boolean onNestedPrePerformAccessibilityAction(View target, int action, Bundle arguments); } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index a8bc5c9..87d9a58 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -6417,6 +6417,11 @@ public final class ViewRootImpl implements ViewParent, return false; } + @Override + public boolean onNestedPrePerformAccessibilityAction(View target, int action, Bundle args) { + return false; + } + void changeCanvasOpacity(boolean opaque) { Log.d(TAG, "changeCanvasOpacity: opaque=" + opaque); if (mAttachInfo.mHardwareRenderer != null) { diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java index ed7af2f..4e48454 100644 --- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java +++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java @@ -20,6 +20,7 @@ package com.android.internal.widget; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Rect; +import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; @@ -31,6 +32,8 @@ import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.ViewParent; import android.view.ViewTreeObserver; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityNodeInfo; import android.view.animation.AnimationUtils; import android.widget.AbsListView; import android.widget.OverScroller; @@ -367,8 +370,14 @@ public class ResolverDrawerLayout extends ViewGroup { child.offsetTopAndBottom((int) dy); } } + final boolean isCollapsedOld = mCollapseOffset != 0; mCollapseOffset = newPos; mTopOffset += dy; + final boolean isCollapsedNew = newPos != 0; + if (isCollapsedOld != isCollapsedNew) { + notifyViewAccessibilityStateChangedIfNeeded( + AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED); + } postInvalidateOnAnimation(); return dy; } @@ -571,6 +580,50 @@ public class ResolverDrawerLayout extends ViewGroup { } @Override + public boolean onNestedPrePerformAccessibilityAction(View target, int action, Bundle args) { + if (super.onNestedPrePerformAccessibilityAction(target, action, args)) { + return true; + } + + if (action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD && mCollapseOffset != 0) { + smoothScrollTo(0, 0); + return true; + } + return false; + } + + @Override + public void onInitializeAccessibilityEvent(AccessibilityEvent event) { + super.onInitializeAccessibilityEvent(event); + event.setClassName(ResolverDrawerLayout.class.getName()); + } + + @Override + public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(info); + info.setClassName(ResolverDrawerLayout.class.getName()); + if (isEnabled()) { + if (mCollapseOffset != 0) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); + info.setScrollable(true); + } + } + } + + @Override + public boolean performAccessibilityAction(int action, Bundle arguments) { + if (super.performAccessibilityAction(action, arguments)) { + return true; + } + + if (action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD && mCollapseOffset != 0) { + smoothScrollTo(0, 0); + return true; + } + return false; + } + + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int sourceWidth = MeasureSpec.getSize(widthMeasureSpec); int widthSize = sourceWidth; @@ -615,7 +668,13 @@ public class ResolverDrawerLayout extends ViewGroup { mUncollapsibleHeight = heightUsed - mCollapsibleHeight; if (isLaidOut()) { + final boolean isCollapsedOld = mCollapseOffset != 0; mCollapseOffset = Math.min(mCollapseOffset, mCollapsibleHeight); + final boolean isCollapsedNew = mCollapseOffset != 0; + if (isCollapsedOld != isCollapsedNew) { + notifyViewAccessibilityStateChangedIfNeeded( + AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED); + } } else { // Start out collapsed at first unless we restored state for otherwise mCollapseOffset = mOpenOnLayout ? 0 : mCollapsibleHeight; |