Skip to content

Instantly share code, notes, and snippets.

@wuyexiong
Created December 2, 2014 07:54
Show Gist options
  • Save wuyexiong/49d10d8c20a6b6f6cb09 to your computer and use it in GitHub Desktop.
Save wuyexiong/49d10d8c20a6b6f6cb09 to your computer and use it in GitHub Desktop.
package com.mi.mishophome.util;
import android.support.v4.util.SparseArrayCompat;
import android.view.View;
import android.widget.AbsListView;
/**
* Created by wuyexiong on 12/2/14.
*/
public class ListViewScrollTracker {
private AbsListView mListView;
private SparseArrayCompat<Integer> mPositions;
private SparseArrayCompat<Integer> mListViewItemHeights = new SparseArrayCompat<>();
private int mFirstVisiblePosition;
private int mScrollY;
public ListViewScrollTracker(final AbsListView listView) {
mListView = listView;
}
/**
* Call from an AbsListView.OnScrollListener to calculate the incremental offset (change in scroll offset
* since the last calculation).
*
* @param firstVisiblePosition First visible item position in the list.
* @param visibleItemCount Number of visible items in the list.
* @return The incremental offset, or 0 if it wasn't possible to calculate the offset.
*/
public int calculateIncrementalOffset(final int firstVisiblePosition, final int visibleItemCount) {
// Remember previous positions, if any
SparseArrayCompat<Integer> previousPositions = mPositions;
// Store new positions
mPositions = new SparseArrayCompat<Integer>();
for (int i = 0; i < visibleItemCount; i++) {
mPositions.put(firstVisiblePosition + i, mListView.getChildAt(i).getTop());
}
if (previousPositions != null) {
// Find position which exists in both mPositions and previousPositions, then return the difference
// of the new and old Y values.
for (int i = 0; i < previousPositions.size(); i++) {
int position = previousPositions.keyAt(i);
int previousTop = previousPositions.get(position);
Integer newTop = mPositions.get(position);
if (newTop != null) {
return newTop - previousTop;
}
}
}
return 0; // No view's position was in both previousPositions and mPositions
}
public int calculateScrollY(final int firstVisiblePosition, final int visibleItemCount) {
mFirstVisiblePosition = firstVisiblePosition;
if (visibleItemCount > 0) {
View c = mListView.getChildAt(0); //this is the first visible row
int scrollY = -c.getTop();
mListViewItemHeights.put(firstVisiblePosition, c.getMeasuredHeight());
for (int i = 0; i < firstVisiblePosition; ++i) {
if (mListViewItemHeights.get(i) != null) // (this is a sanity check)
scrollY += mListViewItemHeights.get(i); //add all heights of the views that are gone
}
mScrollY = scrollY;
return scrollY;
}
return 0;
}
public int getFirstVisiblePosition() {
return mFirstVisiblePosition;
}
public int getScrollY() {
return mScrollY;
}
public void clear() {
mPositions = null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment