OSDN Git Service

Only activate FastScroller when it's needed
authorAlan Viverette <alanv@google.com>
Sat, 7 Sep 2013 02:39:47 +0000 (19:39 -0700)
committerAlan Viverette <alanv@google.com>
Sat, 7 Sep 2013 02:39:47 +0000 (19:39 -0700)
Removes code that was incorrectly handling ACTION_DOWN when the
host ListView started intercepting events for its own use. Fixes
handling of short lists and changes resulting from toggling the
FastScroller enabled state.

BUG: 10651874
Change-Id: I7b088b46d00a372a0a55291db892cc059f1aed20

core/java/android/widget/AbsListView.java
core/java/android/widget/FastScroller.java

index c308024..40a6ab4 100644 (file)
@@ -1250,7 +1250,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
             mFastScroller.setEnabled(true);
         }
 
-        recomputePadding();
+        resolvePadding();
 
         if (mFastScroller != null) {
             mFastScroller.updateLayout();
@@ -1312,7 +1312,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
      * @see #setFastScrollAlwaysVisible(boolean)
      */
     public boolean isFastScrollAlwaysVisible() {
-        return mFastScrollEnabled && mFastScrollAlwaysVisible;
+        if (mFastScroller == null) {
+            return mFastScrollEnabled && mFastScrollAlwaysVisible;
+        } else {
+            return mFastScroller.isEnabled() && mFastScroller.isAlwaysShowEnabled();
+        }
     }
 
     @Override
@@ -1331,7 +1335,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
      */
     @ViewDebug.ExportedProperty
     public boolean isFastScrollEnabled() {
-        return mFastScrollEnabled;
+        if (mFastScroller == null) {
+            return mFastScrollEnabled;
+        } else {
+            return mFastScroller.isEnabled();
+        }
     }
 
     @Override
@@ -1356,7 +1364,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
      */
     @Override
     protected boolean isVerticalScrollBarHidden() {
-        return mFastScrollEnabled;
+        return isFastScrollEnabled();
     }
 
     /**
index c48955f..006b96e 100644 (file)
@@ -152,9 +152,6 @@ class FastScroller {
     /** The number of headers at the top of the view. */
     private int mHeaderCount;
 
-    /** The number of items in the list. */
-    private int mItemCount = -1;
-
     /** The index of the current section. */
     private int mCurrentSection = -1;
 
@@ -324,6 +321,7 @@ class FastScroller {
 
         getSectionsFromIndexer();
         refreshDrawablePressedState();
+        updateLongList(listView.getChildCount(), listView.getCount());
         setScrollbarPosition(mList.getVerticalScrollbarPosition());
         postAutoHide();
     }
@@ -343,14 +341,10 @@ class FastScroller {
      * @param enabled Whether the fast scroll thumb is enabled.
      */
     public void setEnabled(boolean enabled) {
-        mEnabled = enabled;
+        if (mEnabled != enabled) {
+            mEnabled = enabled;
 
-        if (enabled) {
-            if (mAlwaysShow) {
-                setState(STATE_VISIBLE);
-            }
-        } else {
-            stop();
+            onStateDependencyChanged();
         }
     }
 
@@ -358,19 +352,17 @@ class FastScroller {
      * @return Whether the fast scroll thumb is enabled.
      */
     public boolean isEnabled() {
-        return mEnabled;
+        return mEnabled && (mLongList || mAlwaysShow);
     }
 
     /**
      * @param alwaysShow Whether the fast scroll thumb should always be shown
      */
     public void setAlwaysShow(boolean alwaysShow) {
-        mAlwaysShow = alwaysShow;
+        if (mAlwaysShow != alwaysShow) {
+            mAlwaysShow = alwaysShow;
 
-        if (alwaysShow) {
-            setState(STATE_VISIBLE);
-        } else if (mState == STATE_VISIBLE) {
-            postAutoHide();
+            onStateDependencyChanged();
         }
     }
 
@@ -382,6 +374,23 @@ class FastScroller {
         return mAlwaysShow;
     }
 
+    /**
+     * Called when one of the variables affecting enabled state changes.
+     */
+    private void onStateDependencyChanged() {
+        if (isEnabled()) {
+            if (isAlwaysShowEnabled()) {
+                setState(STATE_VISIBLE);
+            } else if (mState == STATE_VISIBLE) {
+                postAutoHide();
+            }
+        } else {
+            stop();
+        }
+
+        mList.resolvePadding();
+    }
+
     public void setScrollBarStyle(int style) {
         if (mScrollBarStyle != style) {
             mScrollBarStyle = style;
@@ -439,6 +448,18 @@ class FastScroller {
             final int firstVisibleItem = mList.getFirstVisiblePosition();
             setThumbPos(getPosFromItemCount(firstVisibleItem, visibleItemCount, totalItemCount));
         }
+
+        updateLongList(visibleItemCount, totalItemCount);
+    }
+
+    private void updateLongList(int visibleItemCount, int totalItemCount) {
+        final boolean longList = visibleItemCount > 0
+                && totalItemCount / visibleItemCount >= MIN_PAGES;
+        if (mLongList != longList) {
+            mLongList = longList;
+
+            onStateDependencyChanged();
+        }
     }
 
     /**
@@ -795,19 +816,8 @@ class FastScroller {
         mList.postDelayed(mDeferHide, FADE_TIMEOUT);
     }
 
-    private boolean isLongList(int visibleItemCount, int totalItemCount) {
-        // Are there enough pages to require fast scroll? Recompute only if
-        // total count changes.
-        if (mItemCount != totalItemCount && visibleItemCount > 0) {
-            mItemCount = totalItemCount;
-            mLongList = mItemCount / visibleItemCount >= MIN_PAGES;
-        }
-
-        return mLongList;
-    }
-
     public void onScroll(int firstVisibleItem, int visibleItemCount, int totalItemCount) {
-        if (!mEnabled || !mAlwaysShow && !isLongList(visibleItemCount, totalItemCount)) {
+        if (!isEnabled()) {
             setState(STATE_NONE);
             return;
         }
@@ -1221,7 +1231,7 @@ class FastScroller {
     }
 
     public boolean onInterceptTouchEvent(MotionEvent ev) {
-        if (!mEnabled) {
+        if (!isEnabled()) {
             return false;
         }
 
@@ -1233,14 +1243,18 @@ class FastScroller {
                     // need to allow the parent time to decide whether it wants
                     // to intercept events. If it does, we will receive a CANCEL
                     // event.
-                    if (mList.isInScrollingContainer()) {
-                        mInitialTouchY = ev.getY();
-                        startPendingDrag();
-                        return false;
+                    if (!mList.isInScrollingContainer()) {
+                        beginDrag();
+                        return true;
                     }
 
-                    beginDrag();
-                    return true;
+                    mInitialTouchY = ev.getY();
+                    startPendingDrag();
+                }
+                break;
+            case MotionEvent.ACTION_MOVE:
+                if (!isPointInside(ev.getX(), ev.getY())) {
+                    cancelPendingDrag();
                 }
                 break;
             case MotionEvent.ACTION_UP:
@@ -1253,7 +1267,7 @@ class FastScroller {
     }
 
     public boolean onInterceptHoverEvent(MotionEvent ev) {
-        if (!mEnabled) {
+        if (!isEnabled()) {
             return false;
         }
 
@@ -1269,18 +1283,11 @@ class FastScroller {
     }
 
     public boolean onTouchEvent(MotionEvent me) {
-        if (!mEnabled) {
+        if (!isEnabled()) {
             return false;
         }
 
         switch (me.getActionMasked()) {
-            case MotionEvent.ACTION_DOWN: {
-                if (isPointInside(me.getX(), me.getY())) {
-                    beginDrag();
-                    return true;
-                }
-            } break;
-
             case MotionEvent.ACTION_UP: {
                 if (mHasPendingDrag) {
                     // Allow a tap to scroll.