Skip to content

Instantly share code, notes, and snippets.

@vishna
Created March 13, 2015 09:47
Show Gist options
  • Save vishna/603f3b633ea5070b52fd to your computer and use it in GitHub Desktop.
Save vishna/603f3b633ea5070b52fd to your computer and use it in GitHub Desktop.
Missing RecyclerView ScrollListener API
package whatever;
import android.support.v7.widget.RecyclerView;
import java.lang.reflect.Field;
import java.util.HashSet;
/**
* Created by vishna on 28/10/14.
*/
public class RecyclerUtils {
public static void addOnScrollListener(RecyclerView recyclerView, RecyclerView.OnScrollListener onScrollListener) {
if (recyclerView == null || onScrollListener == null) {
return;
}
WrappedOnScrollListener wrappedOnScrollListener = getOnScrollListener(recyclerView);
if (wrappedOnScrollListener != null) {
wrappedOnScrollListener.addListener(onScrollListener);
}
}
public static void removeOnScrollListener(RecyclerView recyclerView, RecyclerView.OnScrollListener onScrollListener) {
if (recyclerView == null || onScrollListener == null) {
return;
}
WrappedOnScrollListener wrappedOnScrollListener = getOnScrollListener(recyclerView);
if (wrappedOnScrollListener != null) {
wrappedOnScrollListener.removeListener(onScrollListener);
}
}
public static WrappedOnScrollListener getOnScrollListener(RecyclerView listView) {
if (listView == null)
return null;
WrappedOnScrollListener result = null;
// try to access private OnScrollListener mOnScrollListener; through reflection
try {
Field f = RecyclerView.class.getDeclaredField("mScrollListener");
f.setAccessible(true);
RecyclerView.OnScrollListener onScrollListener = (RecyclerView.OnScrollListener) f.get(listView);
if (onScrollListener == null) {
// no listener whatsoever
result = new WrappedOnScrollListener();
listView.setOnScrollListener(result);
} else if (onScrollListener instanceof WrappedOnScrollListener) {
result = (WrappedOnScrollListener) onScrollListener;
} else {
// a listener has been setup but it's not an instance of the WrappedOnScrollListener class
// replace the existing listener with a wrapper, add existing one to the wrapper
result = new WrappedOnScrollListener();
result.addListener(onScrollListener);
listView.setOnScrollListener(result);
}
} catch (NoSuchFieldException e) {} catch (IllegalAccessException e) {}
return result;
}
public static class WrappedOnScrollListener extends RecyclerView.OnScrollListener {
public void addListener(RecyclerView.OnScrollListener listener) {
listeners.add(listener);
}
public void removeListener(RecyclerView.OnScrollListener listener) {
listeners.remove(listener);
}
HashSet<RecyclerView.OnScrollListener> listeners = new HashSet<RecyclerView.OnScrollListener>();
@Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
for (RecyclerView.OnScrollListener listener : listeners)
listener.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
for (RecyclerView.OnScrollListener listener : listeners)
listener.onScrolled(recyclerView, dx, dy);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment