From 827015edb3037cc44c5133188684da0ec56f4027 Mon Sep 17 00:00:00 2001 From: Alan Viverette Date: Thu, 13 Nov 2014 10:26:53 -0800 Subject: [PATCH] Prevent NPE when computing FastScroller position with no visible items BUG: 18371212 Change-Id: I90b1f540cdc6095e18242b879c50e8060de662ee --- core/java/android/widget/FastScroller.java | 32 ++++++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java index 068790553708f..06bb32c1a3ec3 100644 --- a/core/java/android/widget/FastScroller.java +++ b/core/java/android/widget/FastScroller.java @@ -1194,17 +1194,37 @@ class FastScroller { return MathUtils.constrain((y - offset) / range, 0f, 1f); } + /** + * Calculates the thumb position based on the visible items. + * + * @param firstVisibleItem First visible item, >= 0. + * @param visibleItemCount Number of visible items, >= 0. + * @param totalItemCount Total number of items, >= 0. + * @return + */ private float getPosFromItemCount( int firstVisibleItem, int visibleItemCount, int totalItemCount) { - if (mSectionIndexer == null || mListAdapter == null) { + final SectionIndexer sectionIndexer = mSectionIndexer; + if (sectionIndexer == null || mListAdapter == null) { getSectionsFromIndexer(); } - final boolean hasSections = mSectionIndexer != null && mSections != null + if (visibleItemCount == 0 || totalItemCount == 0) { + // No items are visible. + return 0; + } + + final boolean hasSections = sectionIndexer != null && mSections != null && mSections.length > 0; if (!hasSections || !mMatchDragPosition) { - return (float) firstVisibleItem / (totalItemCount - visibleItemCount); + if (visibleItemCount == totalItemCount) { + // All items are visible. + return 0; + } else { + return (float) firstVisibleItem / (totalItemCount - visibleItemCount); + } } + // Ignore headers. firstVisibleItem -= mHeaderCount; if (firstVisibleItem < 0) { @@ -1222,14 +1242,14 @@ class FastScroller { } // Number of rows in this section. - final int section = mSectionIndexer.getSectionForPosition(firstVisibleItem); - final int sectionPos = mSectionIndexer.getPositionForSection(section); + final int section = sectionIndexer.getSectionForPosition(firstVisibleItem); + final int sectionPos = sectionIndexer.getPositionForSection(section); final int sectionCount = mSections.length; final int positionsInSection; if (section < sectionCount - 1) { final int nextSectionPos; if (section + 1 < sectionCount) { - nextSectionPos = mSectionIndexer.getPositionForSection(section + 1); + nextSectionPos = sectionIndexer.getPositionForSection(section + 1); } else { nextSectionPos = totalItemCount - 1; }