Skip to content

Commit

Permalink
Add SwipeDismissBehavior event binding
Browse files Browse the repository at this point in the history
  • Loading branch information
xfumihiro committed Oct 7, 2015
1 parent 00712ce commit fd3e7cd
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.jakewharton.rxbinding.support.design.widget

import android.support.design.widget.SwipeDismissBehavior
import android.view.View
import rx.Observable

/**
* Create an observable which emits the dismiss events from `view` on [SwipeDismissBehavior].
*
* *Warning:* The created observable keeps a strong reference to `view`. Unsubscribe
* to free this reference.
*/
public inline fun View.dismisses(): Observable<View> = RxSwipeDismissBehavior.dismisses(this)
12 changes: 12 additions & 0 deletions rxbinding-design/src/androidTest/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jakewharton.rxbinding.support.design">

<application>
<activity
android:name="com.jakewharton.rxbinding.support.design.widget.RxSwipeDismissBehaviorTestActivity"
android:theme="@style/Theme.AppCompat"
/>
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.jakewharton.rxbinding.support.design.widget;

import android.app.Instrumentation;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.SwipeDismissBehavior;
import android.support.test.InstrumentationRegistry;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.view.View;
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 android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_UP;
import static com.google.common.truth.Truth.assertThat;
import static com.jakewharton.rxbinding.MotionEventUtil.motionEventAtPosition;

@RunWith(AndroidJUnit4.class)
public final class RxSwipeDismissBehaviorTest {
@Rule public final ActivityTestRule<RxSwipeDismissBehaviorTestActivity> activityRule =
new ActivityTestRule<>(RxSwipeDismissBehaviorTestActivity.class);

private final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
private View view;

@Before public void setUp() {
RxSwipeDismissBehaviorTestActivity activity = activityRule.getActivity();
view = activity.view;
}

@Test public void dismisses() {
((CoordinatorLayout.LayoutParams) view.getLayoutParams()).setBehavior(
new SwipeDismissBehavior());

RecordingObserver<View> o = new RecordingObserver<>();
Subscription subscription = RxSwipeDismissBehavior.dismisses(view)
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(o);
o.assertNoMoreEvents(); // No initial value.

doSwipeGesture(view);
assertThat(o.takeNext()).isEqualTo(view);

subscription.unsubscribe();

doSwipeGesture(view);
o.assertNoMoreEvents();
}

private void doSwipeGesture(View view) {
instrumentation.sendPointerSync(motionEventAtPosition(view, ACTION_DOWN, 50, 0));
instrumentation.sendPointerSync(motionEventAtPosition(view, ACTION_MOVE, 500, 0));
instrumentation.sendPointerSync(motionEventAtPosition(view, ACTION_UP, 500, 0));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.jakewharton.rxbinding.support.design.widget;

import android.app.Activity;
import android.os.Bundle;
import android.support.design.widget.CoordinatorLayout;
import android.view.View;

public class RxSwipeDismissBehaviorTestActivity extends Activity {
CoordinatorLayout parent;
View view;

@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

parent = new CoordinatorLayout(this);
view = new View(this);
view.setLayoutParams(new CoordinatorLayout.LayoutParams(100, 100));
parent.addView(view);

setContentView(parent);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.jakewharton.rxbinding.support.design.widget;

import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import android.support.design.widget.SwipeDismissBehavior;
import android.view.View;
import rx.Observable;

/**
* Static factory methods for creating {@linkplain Observable observables}
* for {@link SwipeDismissBehavior} on (@link View).
*/
public final class RxSwipeDismissBehavior {
/**
* Create an observable which emits the dismiss events from {@code view} on {@link SwipeDismissBehavior}.
* <p>
* <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe
* to free this reference.
*/
@CheckResult @NonNull
public static Observable<View> dismisses(@NonNull View view) {
return Observable.create(new SwipeDismissBehaviorOnSubscribe(view));
}

private RxSwipeDismissBehavior() {
throw new AssertionError("No instances.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.jakewharton.rxbinding.support.design.widget;

import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.SwipeDismissBehavior;
import android.view.View;
import com.jakewharton.rxbinding.internal.MainThreadSubscription;
import rx.Observable;
import rx.Subscriber;

import static com.jakewharton.rxbinding.internal.Preconditions.checkUiThread;

final class SwipeDismissBehaviorOnSubscribe implements Observable.OnSubscribe<View> {
private final View view;

public SwipeDismissBehaviorOnSubscribe(View view) {
this.view = view;
}

@Override public void call(final Subscriber<? super View> subscriber) {
checkUiThread();

SwipeDismissBehavior.OnDismissListener listener = new SwipeDismissBehavior.OnDismissListener() {
@Override public void onDismiss(View view) {
if (!subscriber.isUnsubscribed()) {
subscriber.onNext(view);
}
}

@Override public void onDragStateChanged(int i) {
}
};

if (!(view.getLayoutParams() instanceof CoordinatorLayout.LayoutParams)) {
throw new IllegalArgumentException("The view is not in a Coordinator Layout.");
}
final SwipeDismissBehavior behavior =
(SwipeDismissBehavior) ((CoordinatorLayout.LayoutParams) view.getLayoutParams()).getBehavior();
if (behavior == null) {
throw new IllegalStateException("There's no behavior set on this view.");
}
behavior.setListener(listener);

subscriber.add(new MainThreadSubscription() {
@Override protected void onUnsubscribe() {
behavior.setListener(null);
}
});
}
}

0 comments on commit fd3e7cd

Please sign in to comment.