OSDN Git Service

Fixing errors in position information of scrollable views reported for accessibility.
authorSvetoslav Ganov <svetoslavganov@google.com>
Thu, 6 Oct 2011 05:26:05 +0000 (22:26 -0700)
committerSvetoslav Ganov <svetoslavganov@google.com>
Thu, 6 Oct 2011 21:42:58 +0000 (14:42 -0700)
1. ScrollView/HorizontalScroll view were reporting only the scroll X and Y but
   failed to convey the max scroll along X and Y so the position can be determined.

2. WebView was not reporting correctly its scroll position for accessibility.

3. Some descendants of AdapterView were reporting incorrect position information.

4. Updated the accessibility docs with some details about the scroll information.

5. Cleaned up duplicated code.

bug:5412132
bug:5412265

Change-Id: I165e73ecde027dad811425b9f395a3f758c923ba

core/java/android/view/View.java
core/java/android/view/accessibility/AccessibilityEvent.java
core/java/android/view/accessibility/AccessibilityRecord.java
core/java/android/webkit/WebView.java
core/java/android/widget/AbsListView.java
core/java/android/widget/AdapterView.java
core/java/android/widget/Gallery.java
core/java/android/widget/HorizontalScrollView.java
core/java/android/widget/ListView.java
core/java/android/widget/ScrollView.java

index 8e5aefd..e0192ae 100644 (file)
@@ -4001,23 +4001,13 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
         event.setEnabled(isEnabled());
         event.setContentDescription(mContentDescription);
 
-        final int eventType = event.getEventType();
-        switch (eventType) {
-            case AccessibilityEvent.TYPE_VIEW_FOCUSED: {
-                if (mAttachInfo != null) {
-                    ArrayList<View> focusablesTempList = mAttachInfo.mFocusablesTempList;
-                    getRootView().addFocusables(focusablesTempList, View.FOCUS_FORWARD,
-                            FOCUSABLES_ALL);
-                    event.setItemCount(focusablesTempList.size());
-                    event.setCurrentItemIndex(focusablesTempList.indexOf(this));
-                    focusablesTempList.clear();
-                }
-            } break;
-            case AccessibilityEvent.TYPE_VIEW_SCROLLED: {
-                event.setScrollX(mScrollX);
-                event.setScrollY(mScrollY);
-                event.setItemCount(getHeight());
-            } break;
+        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED && mAttachInfo != null) {
+            ArrayList<View> focusablesTempList = mAttachInfo.mFocusablesTempList;
+            getRootView().addFocusables(focusablesTempList, View.FOCUS_FORWARD,
+                    FOCUSABLES_ALL);
+            event.setItemCount(focusablesTempList.size());
+            event.setCurrentItemIndex(focusablesTempList.indexOf(this));
+            focusablesTempList.clear();
         }
     }
 
index 91fbb0e..25bc559 100644 (file)
@@ -79,6 +79,16 @@ import java.util.List;
  *   <li>{@link #isPassword()} - Whether the source is password.</li>
  *   <li>{@link #isChecked()} - Whether the source is checked.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * </p>
  * <p>
@@ -97,6 +107,16 @@ import java.util.List;
  *   <li>{@link #isPassword()} - Whether the source is password.</li>
  *   <li>{@link #isChecked()} - Whether the source is checked.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * </p>
  * <p>
@@ -117,6 +137,16 @@ import java.util.List;
  *   <li>{@link #getItemCount()} - The number of selectable items of the source.</li>
  *   <li>{@link #getCurrentItemIndex()} - The currently selected item index.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * </p>
  * <p>
@@ -137,6 +167,16 @@ import java.util.List;
  *   <li>{@link #getItemCount()} - The number of focusable items on the screen.</li>
  *   <li>{@link #getCurrentItemIndex()} - The currently focused item index.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * </p>
  * <p>
@@ -218,18 +258,17 @@ import java.util.List;
  *   <li>{@link #getEventTime()}  - The event time.</li>
  *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
- *   <li>{@link #getScrollX()} - The horizontal offset of the source
- *                                (without descendants of AdapterView)).</li>
- *   <li>{@link #getScrollY()} - The vertical offset of the source
- *                                (without descendants of AdapterView)).</li>
- *   <li>{@link #getFromIndex()} - The index of the first visible item of the source
- *                                 (for descendants of AdapterView).</li>
- *   <li>{@link #getToIndex()} - The index of the last visible item of the source
- *                               (for descendants of AdapterView).</li>
- *   <li>{@link #getItemCount()} - The total items of the source (for descendants of AdapterView)
- *                                 or the height of the source in pixels (all other cases).</li>
- *   <li>{@link #getText()} - Text for providing more context.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * <em>Note:</em> This event type is not dispatched to descendants though
  * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
@@ -334,6 +373,16 @@ import java.util.List;
  *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * </p>
  * <b>View hover exit</b> - represents the event of stopping to hover
@@ -350,6 +399,16 @@ import java.util.List;
  *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * </p>
  * <p>
@@ -816,6 +875,8 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
         record.mToIndex = parcel.readInt();
         record.mScrollX = parcel.readInt();
         record.mScrollY =  parcel.readInt();
+        record.mMaxScrollX = parcel.readInt();
+        record.mMaxScrollY =  parcel.readInt();
         record.mAddedCount = parcel.readInt();
         record.mRemovedCount = parcel.readInt();
         record.mClassName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
@@ -868,6 +929,8 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
         parcel.writeInt(record.mToIndex);
         parcel.writeInt(record.mScrollX);
         parcel.writeInt(record.mScrollY);
+        parcel.writeInt(record.mMaxScrollX);
+        parcel.writeInt(record.mMaxScrollY);
         parcel.writeInt(record.mAddedCount);
         parcel.writeInt(record.mRemovedCount);
         TextUtils.writeToParcel(record.mClassName, parcel, flags);
index afd7473..fe06d98 100644 (file)
@@ -73,6 +73,8 @@ public class AccessibilityRecord {
     int mToIndex = UNDEFINED;
     int mScrollX = UNDEFINED;
     int mScrollY = UNDEFINED;
+    int mMaxScrollX = UNDEFINED;
+    int mMaxScrollY = UNDEFINED;
 
     int mAddedCount= UNDEFINED;
     int mRemovedCount = UNDEFINED;
@@ -348,18 +350,18 @@ public class AccessibilityRecord {
     }
 
     /**
-     * Gets the scroll position of the source along the X axis.
+     * Gets the scroll offset of the source left edge in pixels.
      *
-     * @return The scroll along the X axis.
+     * @return The scroll.
      */
     public int getScrollX() {
         return mScrollX;
     }
 
     /**
-     * Sets the scroll position of the source along the X axis.
+     * Sets the scroll offset of the source left edge in pixels.
      *
-     * @param scrollX The scroll along the X axis.
+     * @param scrollX The scroll.
      */
     public void setScrollX(int scrollX) {
         enforceNotSealed();
@@ -367,18 +369,18 @@ public class AccessibilityRecord {
     }
 
     /**
-     * Gets the scroll position of the source along the Y axis.
+     * Gets the scroll offset of the source top edge in pixels.
      *
-     * @return The scroll along the Y axis.
+     * @return The scroll.
      */
     public int getScrollY() {
         return mScrollY;
     }
 
     /**
-     * Sets the scroll position of the source along the Y axis.
+     * Sets the scroll offset of the source top edge in pixels.
      *
-     * @param scrollY The scroll along the Y axis.
+     * @param scrollY The scroll.
      */
     public void setScrollY(int scrollY) {
         enforceNotSealed();
@@ -386,6 +388,51 @@ public class AccessibilityRecord {
     }
 
     /**
+     * Gets the max scroll offset of the source left edge in pixels.
+     *
+     * @return The max scroll.
+     *
+     * @hide
+     */
+    public int getMaxScrollX() {
+        return mMaxScrollX;
+    }
+    /**
+     * Sets the max scroll offset of the source left edge in pixels.
+     *
+     * @param maxScrollX The max scroll.
+     *
+     * @hide
+     */
+    public void setMaxScrollX(int maxScrollX) {
+        enforceNotSealed();
+        mMaxScrollX = maxScrollX;
+    }
+
+    /**
+     * Gets the max scroll offset of the source top edge in pixels.
+     *
+     * @return The max scroll.
+     *
+     * @hide
+     */
+    public int getMaxScrollY() {
+        return mMaxScrollY;
+    }
+
+    /**
+     * Sets the max scroll offset of the source top edge in pixels.
+     *
+     * @param maxScrollY The max scroll.
+     *
+     * @hide
+     */
+    public void setMaxScrollY(int maxScrollY) {
+        enforceNotSealed();
+        mMaxScrollY = maxScrollY;
+    }
+
+    /**
      * Gets the number of added characters.
      *
      * @return The number of added characters.
@@ -658,6 +705,8 @@ public class AccessibilityRecord {
         mToIndex = record.mToIndex;
         mScrollX = record.mScrollX;
         mScrollY = record.mScrollY;
+        mMaxScrollX = record.mMaxScrollX;
+        mMaxScrollY = record.mMaxScrollY;
         mAddedCount = record.mAddedCount;
         mRemovedCount = record.mRemovedCount;
         mClassName = record.mClassName;
@@ -682,6 +731,8 @@ public class AccessibilityRecord {
         mToIndex = UNDEFINED;
         mScrollX = UNDEFINED;
         mScrollY = UNDEFINED;
+        mMaxScrollX = UNDEFINED;
+        mMaxScrollY = UNDEFINED;
         mAddedCount = UNDEFINED;
         mRemovedCount = UNDEFINED;
         mClassName = null;
@@ -711,6 +762,8 @@ public class AccessibilityRecord {
         builder.append("; ToIndex: " + mToIndex);
         builder.append("; ScrollX: " + mScrollX);
         builder.append("; ScrollY: " + mScrollY);
+        builder.append("; MaxScrollX: " + mMaxScrollX);
+        builder.append("; MaxScrollY: " + mMaxScrollY);
         builder.append("; AddedCount: " + mAddedCount);
         builder.append("; RemovedCount: " + mRemovedCount);
         builder.append("; ParcelableData: " + mParcelableData);
index eaed9fe..87c89c6 100644 (file)
@@ -77,7 +77,9 @@ 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.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
@@ -1303,6 +1305,31 @@ public class WebView extends AbsoluteLayout
     }
 
     @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        info.setScrollable(isScrollableForAccessibility());
+    }
+
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(event);
+        event.setScrollable(isScrollableForAccessibility());
+        event.setScrollX(mScrollX);
+        event.setScrollY(mScrollY);
+        final int convertedContentWidth = contentToViewX(getContentWidth());
+        final int adjustedViewWidth = getWidth() - mPaddingLeft - mPaddingRight;
+        event.setMaxScrollX(Math.max(convertedContentWidth - adjustedViewWidth, 0));
+        final int convertedContentHeight = contentToViewY(getContentHeight());
+        final int adjustedViewHeight = getHeight() - mPaddingTop - mPaddingBottom;
+        event.setMaxScrollY(Math.max(convertedContentHeight - adjustedViewHeight, 0));
+    }
+
+    private boolean isScrollableForAccessibility() {
+        return (contentToViewX(getContentWidth()) > getWidth() - mPaddingLeft - mPaddingRight
+                || contentToViewY(getContentHeight()) > getHeight() - mPaddingTop - mPaddingBottom);
+    }
+
+    @Override
     public void setOverScrollMode(int mode) {
         super.setOverScrollMode(mode);
         if (mode != OVER_SCROLL_NEVER) {
index 7b8c7f2..c218f23 100644 (file)
@@ -1270,40 +1270,24 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
     }
 
     @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        info.setScrollable(true);
-    }
-
-    @Override
     public void sendAccessibilityEvent(int eventType) {
         // Since this class calls onScrollChanged even if the mFirstPosition and the
         // child count have not changed we will avoid sending duplicate accessibility
         // events.
         if (eventType == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
-            final int lastPosition = mFirstPosition + getChildCount();
-            if (mLastAccessibilityScrollEventFromIndex == mFirstPosition
-                    && mLastAccessibilityScrollEventToIndex == lastPosition) {
+            final int firstVisiblePosition = getFirstVisiblePosition();
+            final int lastVisiblePosition = getLastVisiblePosition();
+            if (mLastAccessibilityScrollEventFromIndex == firstVisiblePosition
+                    && mLastAccessibilityScrollEventToIndex == lastVisiblePosition) {
                 return;   
             } else {
-                mLastAccessibilityScrollEventFromIndex = mFirstPosition;
-                mLastAccessibilityScrollEventToIndex = lastPosition;       
+                mLastAccessibilityScrollEventFromIndex = firstVisiblePosition;
+                mLastAccessibilityScrollEventToIndex = lastVisiblePosition;
             }
         }
         super.sendAccessibilityEvent(eventType);
     }
 
-    @Override
-    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-        super.onInitializeAccessibilityEvent(event);
-        event.setScrollable(true);
-        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
-            event.setFromIndex(mFirstPosition);
-            event.setToIndex(mFirstPosition +  getChildCount());
-            event.setItemCount(mItemCount);
-        }
-    }
-
     /**
      * Indicates whether the children's drawing cache is used during a scroll.
      * By default, the drawing cache is enabled but this will consume more memory.
index 61c5dd4..fd19b5f 100644 (file)
@@ -29,6 +29,7 @@ import android.view.View;
 import android.view.ViewDebug;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
 
 
 /**
@@ -881,19 +882,10 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup {
 
     @Override
     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
-            // This is an exceptional case which occurs when a window gets the
-            // focus and sends a focus event via its focused child to announce
-            // current focus/selection. AdapterView fires selection but not focus
-            // events so we change the event type here.
-            if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
-                event.setEventType(AccessibilityEvent.TYPE_VIEW_SELECTED);
-            }
-        }
-
         View selectedView = getSelectedView();
-        if (selectedView != null && selectedView.getVisibility() == VISIBLE) {
-            getSelectedView().dispatchPopulateAccessibilityEvent(event);
+        if (selectedView != null && selectedView.getVisibility() == VISIBLE
+                && selectedView.dispatchPopulateAccessibilityEvent(event)) {
+            return true;
         }
         return false;
     }
@@ -913,19 +905,32 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup {
     }
 
     @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        info.setScrollable(isScrollableForAccessibility());
+        View selectedView = getSelectedView();
+        if (selectedView != null) {
+            info.setEnabled(selectedView.isEnabled());
+        }
+    }
+
+    @Override
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(event);
-
+        event.setScrollable(isScrollableForAccessibility());
         View selectedView = getSelectedView();
         if (selectedView != null) {
             event.setEnabled(selectedView.isEnabled());
         }
-        event.setItemCount(getCount());
-        event.setCurrentItemIndex(getSelectedItemPosition());
-        if (getChildCount() > 0) {
-            event.setFromIndex(getFirstVisiblePosition());
-            event.setToIndex(getLastVisiblePosition());
-        }
+        event.setFromIndex(getFirstVisiblePosition());
+        event.setToIndex(getLastVisiblePosition());
+        event.setItemCount(getAdapter().getCount());
+    }
+
+    private boolean isScrollableForAccessibility() {
+        final int itemCount = getAdapter().getCount();
+        return itemCount > 0
+            && (getFirstVisiblePosition() > 0 || getLastVisiblePosition() < itemCount - 1);
     }
 
     @Override
index a0eba9a..5e37fa8 100644 (file)
@@ -32,8 +32,6 @@ import android.view.SoundEffectConstants;
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.animation.Transformation;
 
 import com.android.internal.R;
@@ -354,23 +352,6 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
         return child.getMeasuredHeight();
     }
 
-    @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        info.setScrollable(true);
-    }
-
-    @Override
-    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-        super.onInitializeAccessibilityEvent(event);
-        event.setScrollable(true);
-        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
-            event.setFromIndex(mFirstPosition);
-            event.setToIndex(mFirstPosition +  getChildCount());
-            event.setItemCount(mItemCount);
-        }
-    }
-
     /**
      * Tracks a motion scroll. In reality, this is used to do just about any
      * movement to items (touch scroll, arrow-key scroll, set an item as selected).
index 324dfd7..57701ae 100644 (file)
@@ -716,13 +716,17 @@ public class HorizontalScrollView extends FrameLayout {
     @Override
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
-        info.setScrollable(true);
+        info.setScrollable(getScrollRange() > 0);
     }
 
     @Override
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(event);
-        event.setScrollable(true);
+        event.setScrollable(getScrollRange() > 0);
+        event.setScrollX(mScrollX);
+        event.setScrollY(mScrollY);
+        event.setMaxScrollX(getScrollRange());
+        event.setMaxScrollY(mScrollY);
     }
 
     private int getScrollRange() {
index 42e27b1..9ef1aa1 100644 (file)
@@ -1997,31 +1997,6 @@ public class ListView extends AbsListView {
         }
     }
 
-    @Override
-    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-        super.onInitializeAccessibilityEvent(event);
-
-        // If the item count is less than 15 then subtract disabled items from the count and
-        // position. Otherwise ignore disabled items.
-        int itemCount = 0;
-        int currentItemIndex = getSelectedItemPosition();
-
-        ListAdapter adapter = getAdapter();
-        if (adapter != null) {
-            final int count = adapter.getCount();
-            for (int i = 0; i < count; i++) {
-                if (adapter.isEnabled(i)) {
-                    itemCount++;
-                } else if (i <= currentItemIndex) {
-                    currentItemIndex--;
-                }
-            }
-        }
-
-        event.setItemCount(itemCount);
-        event.setCurrentItemIndex(currentItemIndex);
-    }
-
     /**
      * setSelectionAfterHeaderView set the selection to be the first list item
      * after the header views.
index 3ac4e80..767eaee 100644 (file)
@@ -721,13 +721,18 @@ public class ScrollView extends FrameLayout {
     @Override
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
-        info.setScrollable(true);
+        info.setScrollable(getScrollRange() > 0);
     }
 
     @Override
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(event);
-        event.setScrollable(true);
+        final boolean scrollable = getScrollRange() > 0;
+        event.setScrollable(scrollable);
+        event.setScrollX(mScrollX);
+        event.setScrollY(mScrollY);
+        event.setMaxScrollX(mScrollX);
+        event.setMaxScrollY(getScrollRange());
     }
 
     private int getScrollRange() {