Skip to content

Instantly share code, notes, and snippets.

@mandybess
Last active February 18, 2016 10:24
Show Gist options
  • Save mandybess/5d8714095116c645a729 to your computer and use it in GitHub Desktop.
Save mandybess/5d8714095116c645a729 to your computer and use it in GitHub Desktop.
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import android.widget.AbsListView;
import com.jakewharton.rxbinding.view.ViewEvent;
public final class ListViewScrollEvent extends ViewEvent<AbsListView> {
@CheckResult
@NonNull
public static ListViewScrollEvent create(AbsListView listView, int scrollState,
int firstVisibleItem, int visibleItemCount, int totalItemCount) {
return new ListViewScrollEvent(listView, scrollState, firstVisibleItem, visibleItemCount,
totalItemCount);
}
public final int scrollState;
public final int firstVisibleItem;
public final int visibleItemCount;
public final int totalItemCount;
private ListViewScrollEvent(@NonNull AbsListView view, int scrollState,
int firstVisibleItem, int visibleItemCount, int totalItemCount) {
super(view);
this.scrollState = scrollState;
this.firstVisibleItem = firstVisibleItem;
this.visibleItemCount = visibleItemCount;
this.totalItemCount = totalItemCount;
}
public int scrollState() {
return scrollState;
}
public int firstVisibleItem() {
return firstVisibleItem;
}
public int visibleItemCount() {
return visibleItemCount;
}
public int totalItemCount() {
return totalItemCount;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ListViewScrollEvent that = (ListViewScrollEvent) o;
if (scrollState != that.scrollState) return false;
if (firstVisibleItem != that.firstVisibleItem) return false;
if (visibleItemCount != that.visibleItemCount) return false;
return totalItemCount == that.totalItemCount;
}
@Override
public int hashCode() {
int result = scrollState;
result = 31 * result + firstVisibleItem;
result = 31 * result + visibleItemCount;
result = 31 * result + totalItemCount;
return result;
}
@Override
public String toString() {
return "ListViewScrollEvent{" +
"scrollState=" + scrollState +
", firstVisibleItem=" + firstVisibleItem +
", visibleItemCount=" + visibleItemCount +
", totalItemCount=" + totalItemCount +
'}';
}
}
import android.widget.AbsListView;
import rx.Observable;
import rx.Subscriber;
import rx.android.MainThreadSubscription;
import static com.jakewharton.rxbinding.internal.Preconditions.checkUiThread;
public final class ListViewScrollEventOnSubscribe
implements Observable.OnSubscribe<ListViewScrollEvent> {
final AbsListView view;
public ListViewScrollEventOnSubscribe(AbsListView view) {
this.view = view;
}
@Override
public void call(final Subscriber<? super ListViewScrollEvent> subscriber) {
checkUiThread();
final AbsListView.OnScrollListener listener = new AbsListView.OnScrollListener() {
int currentScrollState = SCROLL_STATE_IDLE;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
this.currentScrollState = scrollState;
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
if (!subscriber.isUnsubscribed()) {
ListViewScrollEvent event = ListViewScrollEvent
.create(view, this.currentScrollState, firstVisibleItem,
visibleItemCount, totalItemCount);
subscriber.onNext(event);
}
}
};
view.setOnScrollListener(listener);
subscriber.add(new MainThreadSubscription() {
@Override
protected void onUnsubscribe() {
view.setOnScrollListener(null);
}
});
}
}
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import rx.Observable;
import static com.google.common.base.Preconditions.checkNotNull;
public final class RxListView {
/**
* Create an observable of scroll events on {@code listView}.
* <p>
* <em>Warning:</em> The created observable keeps a strong reference to {@code listView}.
* Unsubscribe to free this reference.
* * <p>
* <em>Warning:</em> The created observable uses {@link AbsListView#setOnScrollListener(OnScrollListener)}
* to observe scroll changes. Only one observable can be used for a view at a time.
* <p>
*/
@CheckResult
@NonNull
public static Observable<ListViewScrollEvent> scrollEvents(@NonNull AbsListView view) {
checkNotNull(view, "view == null");
return Observable.create(new ListScrollEventOnSubscribe(view));
}
}
import android.app.Instrumentation;
import android.support.test.InstrumentationRegistry;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.widget.ListView;
import com.jakewharton.rxbinding.RecordingObserver;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import static com.google.common.truth.Truth.assertThat;
@RunWith(AndroidJUnit4.class)
public final class RxListViewTest {
@Rule
public final ActivityTestRule<RxListViewTestActivity> activityRule =
new ActivityTestRule<>(RxListViewTestActivity.class);
private Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
private RxListViewTestActivity activity;
private ListView listView;
@Before
public void setUp() {
activity = activityRule.getActivity();
listView = activity.listView;
}
@Test
public void scrollEvents() {
RecordingObserver<ListViewScrollEvent> o = new RecordingObserver<>();
Subscription subscription = RxListView.scrollEvents(listView) //
.subscribeOn(AndroidSchedulers.mainThread()) //
.subscribe(o);
o.assertNoMoreEvents();
instrumentation.runOnMainSync(new Runnable() {
@Override
public void run() {
listView.smoothScrollToPosition(50);
}
});
ListViewScrollEvent event = o.takeNext();
assertThat(event.view()).isEqualTo(listView);
assertThat(event.firstVisibleItem()).isEqualTo(2);
assertThat(event.totalItemCount()).isEqualTo(100);
subscription.unsubscribe();
instrumentation.runOnMainSync(new Runnable() {
@Override
public void run() {
listView.smoothScrollToPosition(100);
}
});
o.assertNoMoreEvents();
}
}
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public final class RxListViewTestActivity extends Activity {
ListView listView;
List<String> values;
ArrayAdapter<String> adapter;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
values = createValues(100);
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, values);
listView = new ListView(this);
listView.setAdapter(adapter);
FrameLayout layout = new FrameLayout(this);
layout.addView(listView);
setContentView(layout);
}
private static List<String> createValues(int count) {
final List<String> values = new ArrayList<String>(count);
for (int i = 0; i < count; i++) {
values.add(String.valueOf(i));
}
return values;
}
}
@EllySmore
Copy link

prob does the same but use this import static com.jakewharton.rxbinding.internal.Preconditions.checkNotNull;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment