diff --git a/rxbinding/src/androidTest/AndroidManifest.xml b/rxbinding/src/androidTest/AndroidManifest.xml index 5e20ebed..0d438f24 100644 --- a/rxbinding/src/androidTest/AndroidManifest.xml +++ b/rxbinding/src/androidTest/AndroidManifest.xml @@ -12,6 +12,8 @@ + + activityRule = + new ActivityTestRule<>(RxDatePickerTestActivity.class); + + /** + * The time picker view + */ + private DatePicker datePicker; + + /** + * The instrumentation object + */ + private final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); + + @Before + public void setUp() { + datePicker = activityRule.getActivity().datePicker; + } + + @Test + public void testDateChanges() { + RecordingObserver o = new RecordingObserver<>(); + Subscription subscription = RxDatePicker.init(datePicker, 2016, 5, 10) // + .subscribeOn(AndroidSchedulers.mainThread()) // + .subscribe(o); + assertThat(o.takeNext()).isEqualTo(DatePickerChangeEvent.create(datePicker, 2016, 5, 10)); + + instrumentation.runOnMainSync(new Runnable() { + @Override + public void run() { + datePicker.updateDate(2016, 1, 1); + datePicker.updateDate(2016, 1, 2); + datePicker.updateDate(2016, 2, 2); + datePicker.updateDate(2017, 11, 25); + } + }); + assertThat(o.takeNext()).isEqualTo(DatePickerChangeEvent.create(datePicker, 2016, 1, 1)); + assertThat(o.takeNext()).isEqualTo(DatePickerChangeEvent.create(datePicker, 2016, 1, 2)); + assertThat(o.takeNext()).isEqualTo(DatePickerChangeEvent.create(datePicker, 2016, 2, 2)); + assertThat(o.takeNext()).isEqualTo(DatePickerChangeEvent.create(datePicker, 2017, 11, 25)); + + subscription.unsubscribe(); + } + + @Test + @UiThreadTest + public void testUpdateDate(){ + Action1 action = RxDatePicker.updateYear(datePicker); + action.call(1); + assertThat(datePicker.getYear()).isEqualTo(1); + action.call(12); + assertThat(datePicker.getYear()).isEqualTo(12); + + Action1 action2 = RxDatePicker.updateDayOfMonth(datePicker); + action2.call(25); + assertThat(datePicker.getDayOfMonth()).isEqualTo(25); + action2.call(2); + assertThat(datePicker.getDayOfMonth()).isEqualTo(2); + + Action1 action3 = RxDatePicker.updateMonthOfYear(datePicker); + action3.call(11); + assertThat(datePicker.getMonth()).isEqualTo(11); + action3.call(5); + assertThat(datePicker.getMonth()).isEqualTo(5); + } + + @Test + @UiThreadTest + @TargetApi(21) + public void testSetFirstDayOfWeek(){ + Action1 action = RxDatePicker.firstDayOfWeek(datePicker); + action.call(1); + assertThat(datePicker.getFirstDayOfWeek()).isEqualTo(1); + action.call(7); + assertThat(datePicker.getFirstDayOfWeek()).isEqualTo(7); + assertThat(datePicker.getFirstDayOfWeek()).isNotEqualTo(5); + } + + @Test + @UiThreadTest + public void testMaxMinDate(){ + Action1 action = RxDatePicker.maxDate(datePicker); + action.call(1L); + assertThat(datePicker.getMaxDate()).isEqualTo(1L); + action.call(1232131232131L); + assertThat(datePicker.getMaxDate()).isEqualTo(1232131232131L); + + Action1 action2 = RxDatePicker.minDate(datePicker); + action2.call(12L); + assertThat(datePicker.getMinDate()).isEqualTo(12L); + action2.call(3232L); + assertThat(datePicker.getMinDate()).isEqualTo(3232L); + } + + @Test + @UiThreadTest + public void testShownSpinners(){ + Action1 action = RxDatePicker.spinnersShown(datePicker); +// action.call(true); + datePicker.setSpinnersShown(true); + //it is false because the spinners are not shown on calendar mode + assertThat(datePicker.getSpinnersShown()).isFalse(); + action.call(false); + assertThat(datePicker.getSpinnersShown()).isFalse(); + + } + +} diff --git a/rxbinding/src/androidTest/java/com/jakewharton/rxbinding/widget/RxDatePickerTestActivity.java b/rxbinding/src/androidTest/java/com/jakewharton/rxbinding/widget/RxDatePickerTestActivity.java new file mode 100644 index 00000000..15c971cb --- /dev/null +++ b/rxbinding/src/androidTest/java/com/jakewharton/rxbinding/widget/RxDatePickerTestActivity.java @@ -0,0 +1,19 @@ +package com.jakewharton.rxbinding.widget; + +import android.app.Activity; +import android.os.Bundle; +import android.widget.DatePicker; + +public class RxDatePickerTestActivity extends Activity { + + DatePicker datePicker; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + datePicker = new DatePicker(this); + setContentView(datePicker); + } + +} diff --git a/rxbinding/src/androidTest/java/com/jakewharton/rxbinding/widget/RxRatingBarTest.java b/rxbinding/src/androidTest/java/com/jakewharton/rxbinding/widget/RxRatingBarTest.java index 76c7ac40..a5938302 100644 --- a/rxbinding/src/androidTest/java/com/jakewharton/rxbinding/widget/RxRatingBarTest.java +++ b/rxbinding/src/androidTest/java/com/jakewharton/rxbinding/widget/RxRatingBarTest.java @@ -65,8 +65,8 @@ @Test public void ratingChangeEvents() { RecordingObserver o = new RecordingObserver<>(); - Subscription subscription = RxRatingBar.ratingChangeEvents(view) // - .subscribeOn(AndroidSchedulers.mainThread()) // + Subscription subscription = RxRatingBar.ratingChangeEvents(view) + .subscribeOn(AndroidSchedulers.mainThread()) .subscribe(o); assertThat(o.takeNext()).isEqualTo(RatingBarChangeEvent.create(view, 0f, false)); diff --git a/rxbinding/src/androidTest/java/com/jakewharton/rxbinding/widget/RxTimePickerTest.java b/rxbinding/src/androidTest/java/com/jakewharton/rxbinding/widget/RxTimePickerTest.java new file mode 100644 index 00000000..3420f947 --- /dev/null +++ b/rxbinding/src/androidTest/java/com/jakewharton/rxbinding/widget/RxTimePickerTest.java @@ -0,0 +1,116 @@ +package com.jakewharton.rxbinding.widget; + +import android.app.Instrumentation; +import android.support.test.InstrumentationRegistry; +import android.support.test.annotation.UiThreadTest; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; +import android.widget.TimePicker; + +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 rx.functions.Action1; + +import static com.google.common.truth.Truth.assertThat; + +@RunWith(AndroidJUnit4.class) +public class RxTimePickerTest { + @Rule + public final ActivityTestRule activityRule = + new ActivityTestRule<>(RxTimePickerTestActivity.class); + + /** + * The time picker view + */ + private TimePicker timePicker; + + /** + * The instrumentation object + */ + private final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); + + @Before + public void setUp() { + timePicker = activityRule.getActivity().timePicker; + } + + @Test + public void testTimeChanges() { + RecordingObserver o = new RecordingObserver<>(); + Subscription subscription = RxTimePicker.timeChange(timePicker) // + .subscribeOn(AndroidSchedulers.mainThread()) // + .subscribe(o); + assertThat(o.takeNext()).isNotNull(); + + instrumentation.runOnMainSync(new Runnable() { + @Override + public void run() { + timePicker.setCurrentMinute(59); + timePicker.setCurrentHour(11); + timePicker.setCurrentMinute(23); + } + }); + TimePickerTimeChangeEvent event = o.takeNext(); + assertThat(event).isEqualTo(TimePickerTimeChangeEvent.create(timePicker, event.getHourOfDay(), 59)); + + + //there is a bug in the android system that calls onTimeChange twice + o.takeNext(); + event = o.takeNext(); + assertThat(event).isEqualTo(TimePickerTimeChangeEvent.create(timePicker, 11, event.getMinute())); + + //there is a bug in the android system that calls onTimeChange twice + o.takeNext(); + event = o.takeNext(); + assertThat(event).isEqualTo(TimePickerTimeChangeEvent.create(timePicker, event.getHourOfDay(), 23)); + + subscription.unsubscribe(); + } + + @Test + @UiThreadTest + public void testIs24HourMode() { + Action1 action = RxTimePicker.is24HourView(timePicker); + action.call(true); + assertThat(timePicker.is24HourView()).isTrue(); + action.call(false); + assertThat(timePicker.is24HourView()).isFalse(); + } + + + @Test + @UiThreadTest + public void testHour() { + Action1 action = RxTimePicker.hour(timePicker); + action.call(12); + assertThat(timePicker.getCurrentHour()).isEqualTo(12); + action.call(13); + assertThat(timePicker.getCurrentHour()).isEqualTo(13); + action.call(1); + assertThat(timePicker.getCurrentHour()).isEqualTo(1); + action.call(23); + assertThat(timePicker.getCurrentHour()).isEqualTo(23); + } + + @Test + @UiThreadTest + public void testMinute() { + Action1 action = RxTimePicker.minute(timePicker); + action.call(59); + assertThat(timePicker.getCurrentMinute()).isEqualTo(59); + action.call(13); + assertThat(timePicker.getCurrentMinute()).isEqualTo(13); + action.call(45); + assertThat(timePicker.getCurrentMinute()).isEqualTo(45); + action.call(33); + assertThat(timePicker.getCurrentMinute()).isEqualTo(33); + } + +} diff --git a/rxbinding/src/androidTest/java/com/jakewharton/rxbinding/widget/RxTimePickerTestActivity.java b/rxbinding/src/androidTest/java/com/jakewharton/rxbinding/widget/RxTimePickerTestActivity.java new file mode 100644 index 00000000..f5de27d6 --- /dev/null +++ b/rxbinding/src/androidTest/java/com/jakewharton/rxbinding/widget/RxTimePickerTestActivity.java @@ -0,0 +1,18 @@ +package com.jakewharton.rxbinding.widget; + +import android.app.Activity; +import android.os.Bundle; +import android.widget.TimePicker; + +public final class RxTimePickerTestActivity extends Activity { + + TimePicker timePicker; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + timePicker = new TimePicker(this); + setContentView(timePicker); + } +} diff --git a/rxbinding/src/main/java/com/jakewharton/rxbinding/widget/DatePickerChangeEvent.java b/rxbinding/src/main/java/com/jakewharton/rxbinding/widget/DatePickerChangeEvent.java new file mode 100644 index 00000000..be234c11 --- /dev/null +++ b/rxbinding/src/main/java/com/jakewharton/rxbinding/widget/DatePickerChangeEvent.java @@ -0,0 +1,77 @@ +package com.jakewharton.rxbinding.widget; + +import android.support.annotation.CheckResult; +import android.support.annotation.NonNull; +import android.widget.DatePicker; + +import com.jakewharton.rxbinding.view.ViewEvent; + +public class DatePickerChangeEvent extends ViewEvent { + + @CheckResult + @NonNull + public static DatePickerChangeEvent create(@NonNull DatePicker view, int year, int monthOfYear, + int dayOfMonth) { + return new DatePickerChangeEvent(view, year, monthOfYear, dayOfMonth); + } + + private int year; + + private int monthOfYear; + + private int dayOfMonth; + + private DatePickerChangeEvent(@NonNull DatePicker view, int year, int monthOfYear, + int dayOfMonth) { + super(view); + this.year = year; + this.monthOfYear = monthOfYear; + this.dayOfMonth = dayOfMonth; + } + + public int getYear() { + return year; + } + + public int getMonthOfYear() { + return monthOfYear; + } + + public int getDayOfMonth() { + return dayOfMonth; + } + + @Override + public int hashCode() { + int result = 17; + result = result * 37 + view().hashCode(); + result = result * 37 + year; + result = result * 37 + monthOfYear; + result = result * 37 + dayOfMonth; + return result; + } + + @Override + public boolean equals(Object o) { + if (o instanceof DatePickerChangeEvent) { + DatePickerChangeEvent other = (DatePickerChangeEvent) o; + return this == other || this.year == other.getYear() + && this.monthOfYear == other.getMonthOfYear() + && this.dayOfMonth == other.getDayOfMonth(); + } + return false; + } + + @Override + public String toString() { + return "DatePickerChangeEvent{view=" + + view() + + ", year=" + + year + + ", monthOfYear=" + + monthOfYear + + ", dayOfMonth " + + dayOfMonth + + '}'; + } +} diff --git a/rxbinding/src/main/java/com/jakewharton/rxbinding/widget/DatePickerChangeOnSubscribe.java b/rxbinding/src/main/java/com/jakewharton/rxbinding/widget/DatePickerChangeOnSubscribe.java new file mode 100644 index 00000000..4aaccdda --- /dev/null +++ b/rxbinding/src/main/java/com/jakewharton/rxbinding/widget/DatePickerChangeOnSubscribe.java @@ -0,0 +1,72 @@ +package com.jakewharton.rxbinding.widget; + +import android.widget.DatePicker; + +import rx.Observable; +import rx.Subscriber; +import rx.android.MainThreadSubscription; + +import static rx.android.MainThreadSubscription.verifyMainThread; + +/** + * Observable that emits date change events + */ +public class DatePickerChangeOnSubscribe implements Observable.OnSubscribe { + + /** + * The current year + */ + private int year; + + /** + * The current month of the year + */ + private int monthOfYear; + + /** + * The current day of the month + */ + private int dayOfMonth; + + /** + * The DatePicker object that emits + */ + private DatePicker datePicker; + + public DatePickerChangeOnSubscribe(DatePicker datePicker, int year, int monthOfYear, + int dayOfMonth) { + this.datePicker = datePicker; + this.year = year; + this.monthOfYear = monthOfYear; + this.dayOfMonth = dayOfMonth; + } + + @Override + public void call(final Subscriber subscriber) { + verifyMainThread(); + + DatePicker.OnDateChangedListener onDateChangedListener + = new DatePicker.OnDateChangedListener() { + @Override + public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) { + if (!subscriber.isUnsubscribed()) { + subscriber.onNext(DatePickerChangeEvent.create(view, year, monthOfYear, + dayOfMonth)); + } + } + }; + datePicker.init(year, monthOfYear, dayOfMonth, onDateChangedListener); + + subscriber.add(new MainThreadSubscription() { + @Override + protected void onUnsubscribe() { + datePicker.init(datePicker.getYear(), datePicker.getMonth(), + datePicker.getDayOfMonth(), null); + } + }); + + // Emit initial value + subscriber.onNext(DatePickerChangeEvent.create(datePicker, datePicker.getYear(), + datePicker.getMonth(), datePicker.getDayOfMonth())); + } +} diff --git a/rxbinding/src/main/java/com/jakewharton/rxbinding/widget/RxDatePicker.java b/rxbinding/src/main/java/com/jakewharton/rxbinding/widget/RxDatePicker.java new file mode 100644 index 00000000..ab1e0eb1 --- /dev/null +++ b/rxbinding/src/main/java/com/jakewharton/rxbinding/widget/RxDatePicker.java @@ -0,0 +1,172 @@ +package com.jakewharton.rxbinding.widget; + +import android.annotation.TargetApi; +import android.support.annotation.CheckResult; +import android.support.annotation.NonNull; +import android.widget.DatePicker; + +import rx.Observable; +import rx.functions.Action1; + +import static com.jakewharton.rxbinding.internal.Preconditions.checkNotNull; + +/** + * Static factory methods for creating {@linkplain Observable observables} for + * {@link android.widget.DatePicker}. + */ +public class RxDatePicker { + + private RxDatePicker() { + throw new AssertionError("No instances."); + } + + + /** + * Create an observable of the time change events on {@code view}. + *

+ * Warning: The created observable keeps a strong reference to {@code view}. + * Unsubscribe to free this reference. + *

+ * Note: A value will be emitted immediately on subscribe. + */ + @CheckResult + @NonNull + public static Observable init(@NonNull DatePicker view, int year, + int monthOfYear, int dayOfMonth) { + checkNotNull(view, "view == null"); + return Observable.create(new DatePickerChangeOnSubscribe(view, year, monthOfYear, + dayOfMonth)); + } + + /** + * An action which updates the year + *

+ * Warning: The created observable keeps a strong reference to {@code view}. + * Unsubscribe to free this reference. + */ + @CheckResult + @NonNull + @TargetApi(21) + public static Action1 updateYear(@NonNull final DatePicker view) { + checkNotNull(view, "view == null"); + return new Action1() { + @Override + public void call(Integer newYear) { + view.updateDate(newYear, view.getMonth(), view.getDayOfMonth()); + } + }; + } + + /** + * An action which updates the month of the year + *

+ * Warning: The created observable keeps a strong reference to {@code view}. + * Unsubscribe to free this reference. + */ + @CheckResult + @NonNull + @TargetApi(21) + public static Action1 updateMonthOfYear(@NonNull final DatePicker view) { + checkNotNull(view, "view == null"); + return new Action1() { + @Override + public void call(Integer newMonth) { + view.updateDate(view.getYear(), newMonth, view.getDayOfMonth()); + } + }; + } + + /** + * An action which updates the day of the month + *

+ * Warning: The created observable keeps a strong reference to {@code view}. + * Unsubscribe to free this reference. + */ + @CheckResult + @NonNull + @TargetApi(21) + public static Action1 updateDayOfMonth(@NonNull final DatePicker view) { + checkNotNull(view, "view == null"); + return new Action1() { + @Override + public void call(Integer newDay) { + view.updateDate(view.getYear(), view.getMonth(), newDay); + } + }; + } + + /** + * An action which sets the first day of week + *

+ * Warning: The created observable keeps a strong reference to {@code view}. + * Unsubscribe to free this reference. + */ + @CheckResult + @NonNull + @TargetApi(21) + public static Action1 firstDayOfWeek(@NonNull final DatePicker view) { + checkNotNull(view, "view == null"); + return new Action1() { + @Override + public void call(Integer value) { + view.setFirstDayOfWeek(value); + } + }; + } + + /** + * An action which sets the maximal date supported by this {@link DatePicker} in + * milliseconds since January 1, 1970 00:00:00 in + *

+ * Warning: The created observable keeps a strong reference to {@code view}. + * Unsubscribe to free this reference. + */ + @CheckResult + @NonNull + public static Action1 maxDate(@NonNull final DatePicker view) { + checkNotNull(view, "view == null"); + return new Action1() { + @Override + public void call(Long value) { + view.setMaxDate(value); + } + }; + } + + /** + * An action which sets the minimal date supported by this {@link DatePicker} in + * milliseconds since January 1, 1970 00:00:00 in + *

+ * Warning: The created observable keeps a strong reference to {@code view}. + * Unsubscribe to free this reference. + */ + @CheckResult + @NonNull + public static Action1 minDate(@NonNull final DatePicker view) { + checkNotNull(view, "view == null"); + return new Action1() { + @Override + public void call(Long value) { + view.setMinDate(value); + } + }; + } + + /** + * An action which sets whether {@code view} show spinners. + *

+ * Warning: The created observable keeps a strong reference to {@code view}. + * Unsubscribe to free this reference. + */ + @CheckResult + @NonNull + public static Action1 spinnersShown(@NonNull final DatePicker view) { + checkNotNull(view, "view == null"); + return new Action1() { + @Override + public void call(Boolean value) { + view.setSpinnersShown(value); + } + }; + } +} diff --git a/rxbinding/src/main/java/com/jakewharton/rxbinding/widget/RxTimePicker.java b/rxbinding/src/main/java/com/jakewharton/rxbinding/widget/RxTimePicker.java new file mode 100644 index 00000000..ade45160 --- /dev/null +++ b/rxbinding/src/main/java/com/jakewharton/rxbinding/widget/RxTimePicker.java @@ -0,0 +1,99 @@ +package com.jakewharton.rxbinding.widget; + +import android.support.annotation.CheckResult; +import android.support.annotation.NonNull; +import android.widget.TimePicker; + +import rx.Observable; +import rx.functions.Action1; + +import static com.jakewharton.rxbinding.internal.Preconditions.checkNotNull; + +/** + * Static factory methods for creating {@linkplain Observable observables} for + * {@link android.widget.TimePicker}. + */ +public final class RxTimePicker { + + private RxTimePicker() { + throw new AssertionError("No instances."); + } + + /** + * Create an observable of the time change events on {@code view}. + *

+ * Warning: The created observable keeps a strong reference to {@code view}. + * Unsubscribe to free this reference. + *

+ * Note: A value will be emitted immediately on subscribe. + */ + @CheckResult + @NonNull + public static Observable timeChange(@NonNull TimePicker view) { + checkNotNull(view, "view == null"); + return Observable.create(new TimePickerTimeChangeOnSubscribe(view)); + } + + /** + * An action which sets whether {@code view} is a 24 hour view. + *

+ * Warning: The created observable keeps a strong reference to {@code view}. + * Unsubscribe to free this reference. + */ + @CheckResult + @NonNull + public static Action1 is24HourView(@NonNull final TimePicker view) { + checkNotNull(view, "view == null"); + return new Action1() { + @Override + public void call(Boolean value) { + view.setIs24HourView(value); + } + }; + } + + /** + * An action which sets the hour of {@code view}. + *

+ * Warning: The created observable keeps a strong reference to {@code view}. + * Unsubscribe to free this reference. + */ + @CheckResult + @NonNull + public static Action1 hour(@NonNull final TimePicker view) { + checkNotNull(view, "view == null"); + return new Action1() { + @Override + public void call(Integer value) { + if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) { + view.setCurrentHour(value); + } else { + view.setHour(value); + } + } + }; + } + + /** + * An action which sets the minute of {@code view}. + *

+ * Warning: The created observable keeps a strong reference to {@code view}. + * Unsubscribe to free this reference. + */ + @CheckResult + @NonNull + public static Action1 minute(@NonNull final TimePicker view) { + checkNotNull(view, "view == null"); + return new Action1() { + @Override + public void call(Integer value) { + if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) { + view.setCurrentMinute(value); + } else { + view.setMinute(value); + } + } + }; + } + +} diff --git a/rxbinding/src/main/java/com/jakewharton/rxbinding/widget/TimePickerTimeChangeEvent.java b/rxbinding/src/main/java/com/jakewharton/rxbinding/widget/TimePickerTimeChangeEvent.java new file mode 100644 index 00000000..99cc811f --- /dev/null +++ b/rxbinding/src/main/java/com/jakewharton/rxbinding/widget/TimePickerTimeChangeEvent.java @@ -0,0 +1,82 @@ +package com.jakewharton.rxbinding.widget; + +import android.support.annotation.CheckResult; +import android.support.annotation.NonNull; +import android.widget.TimePicker; + +import com.jakewharton.rxbinding.view.ViewEvent; + +/** + * Class that wraps a time change event + */ +public class TimePickerTimeChangeEvent extends ViewEvent { + + @CheckResult + @NonNull + public static TimePickerTimeChangeEvent create(@NonNull TimePicker view, int hourOfDay, + int minute) { + return new TimePickerTimeChangeEvent(view, hourOfDay, minute); + } + + /** + * The hour of the day that was selected + */ + private int hourOfDay; + + /** + * The minute in hour that was selected + */ + private int minute; + + private TimePickerTimeChangeEvent(@NonNull TimePicker view, int hourOfDay, int minute) { + super(view); + this.hourOfDay = hourOfDay; + this.minute = minute; + } + + /** + * Get the current hour + * @return int + */ + public int getHourOfDay() { + return hourOfDay; + } + + /** + * Get the current minute + * @return int + */ + public int getMinute() { + return minute; + } + + @Override + public int hashCode() { + int result = 17; + result = result * 37 + view().hashCode(); + result = result * 37 + hourOfDay; + result = result * 37 + minute; + return result; + } + + @Override + public boolean equals(Object o) { + if (o instanceof TimePickerTimeChangeEvent) { + TimePickerTimeChangeEvent other = (TimePickerTimeChangeEvent) o; + return this == other || this.hourOfDay == other.getHourOfDay() + && this.minute == other.getMinute(); + } + return false; + } + + @Override + public String toString() { + return "TimePickerTimeChangeEvenet{view=" + + view() + + ", hourOfDay=" + + hourOfDay + + ", minute=" + + minute + + '}'; + } +} diff --git a/rxbinding/src/main/java/com/jakewharton/rxbinding/widget/TimePickerTimeChangeOnSubscribe.java b/rxbinding/src/main/java/com/jakewharton/rxbinding/widget/TimePickerTimeChangeOnSubscribe.java new file mode 100644 index 00000000..9bed4e45 --- /dev/null +++ b/rxbinding/src/main/java/com/jakewharton/rxbinding/widget/TimePickerTimeChangeOnSubscribe.java @@ -0,0 +1,58 @@ +package com.jakewharton.rxbinding.widget; + +import android.widget.TimePicker; + +import rx.Observable; +import rx.Subscriber; +import rx.android.MainThreadSubscription; + +import static rx.android.MainThreadSubscription.verifyMainThread; + +/** + * Observable that emits time change events + */ +public class TimePickerTimeChangeOnSubscribe + implements Observable.OnSubscribe { + + /** + * The time picker that emits events + */ + private TimePicker timePicker; + + protected TimePickerTimeChangeOnSubscribe(TimePicker timePicker) { + this.timePicker = timePicker; + } + + @Override + public void call(final Subscriber subscriber) { + verifyMainThread(); + + TimePicker.OnTimeChangedListener onTimeChangedListener + = new TimePicker.OnTimeChangedListener() { + @Override + public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { + if (!subscriber.isUnsubscribed()) { + subscriber.onNext(TimePickerTimeChangeEvent.create(timePicker, hourOfDay, + minute)); + } + } + }; + timePicker.setOnTimeChangedListener(onTimeChangedListener); + + subscriber.add(new MainThreadSubscription() { + @Override + protected void onUnsubscribe() { + timePicker.setOnTimeChangedListener(null); + } + }); + + // Emit initial value + if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) { + subscriber.onNext(TimePickerTimeChangeEvent.create(timePicker, + timePicker.getCurrentHour(), timePicker.getCurrentMinute())); + } else { + subscriber.onNext(TimePickerTimeChangeEvent.create(timePicker, timePicker.getHour(), + timePicker.getMinute())); + } + } +}