package com.jakewharton.rxbinding2.widget; import android.support.annotation.CheckResult; import android.support.annotation.NonNull; import android.widget.TextView; import com.jakewharton.rxbinding2.InitialValueObservable; import com.jakewharton.rxbinding2.internal.Functions; import io.reactivex.Observable; import io.reactivex.functions.Consumer; import io.reactivex.functions.Predicate; import static com.jakewharton.rxbinding2.internal.Preconditions.checkNotNull; /** * Static factory methods for creating {@linkplain Observable observables} and {@linkplain Consumer * actions} for {@link TextView}. */ public final class RxTextView { /** * Create an observable of editor actions on {@code view}. * <p> * <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe * to free this reference. * <p> * <em>Warning:</em> The created observable uses {@link TextView.OnEditorActionListener} to * observe actions. Only one observable can be used for a view at a time. */ @CheckResult @NonNull public static Observable<Integer> editorActions(@NonNull TextView view) { checkNotNull(view, "view == null"); return editorActions(view, Functions.PREDICATE_ALWAYS_TRUE); } /** * Create an observable of editor actions on {@code view}. * <p> * <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe * to free this reference. * <p> * <em>Warning:</em> The created observable uses {@link TextView.OnEditorActionListener} to * observe actions. Only one observable can be used for a view at a time. * * @param handled Predicate invoked each occurrence to determine the return value of the * underlying {@link TextView.OnEditorActionListener}. */ @CheckResult @NonNull public static Observable<Integer> editorActions(@NonNull TextView view, @NonNull Predicate<? super Integer> handled) { checkNotNull(view, "view == null"); checkNotNull(handled, "handled == null"); return new TextViewEditorActionObservable(view, handled); } /** * Create an observable of editor action events on {@code view}. * <p> * <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe * to free this reference. * <p> * <em>Warning:</em> The created observable uses {@link TextView.OnEditorActionListener} to * observe actions. Only one observable can be used for a view at a time. */ @CheckResult @NonNull public static Observable<TextViewEditorActionEvent> editorActionEvents(@NonNull TextView view) { checkNotNull(view, "view == null"); return editorActionEvents(view, Functions.PREDICATE_ALWAYS_TRUE); } /** * Create an observable of editor action events on {@code view}. * <p> * <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe * to free this reference. * <p> * <em>Warning:</em> The created observable uses {@link TextView.OnEditorActionListener} to * observe actions. Only one observable can be used for a view at a time. * * @param handled Predicate invoked each occurrence to determine the return value of the * underlying {@link TextView.OnEditorActionListener}. */ @CheckResult @NonNull public static Observable<TextViewEditorActionEvent> editorActionEvents(@NonNull TextView view, @NonNull Predicate<? super TextViewEditorActionEvent> handled) { checkNotNull(view, "view == null"); checkNotNull(handled, "handled == null"); return new TextViewEditorActionEventObservable(view, handled); } /** * Create an observable of character sequences for text changes on {@code view}. * <p> * <em>Warning:</em> Values emitted by this observable are <b>mutable</b> and owned by the host * {@code TextView} and thus are <b>not safe</b> to cache or delay reading (such as by observing * on a different thread). If you want to cache or delay reading the items emitted then you must * map values through a function which calls {@link String#valueOf} or * {@link CharSequence#toString() .toString()} to create a copy. * <p> * <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe * to free this reference. * <p> * <em>Note:</em> A value will be emitted immediately on subscribe. */ @CheckResult @NonNull public static InitialValueObservable<CharSequence> textChanges(@NonNull TextView view) { checkNotNull(view, "view == null"); return new TextViewTextObservable(view); } /** * Create an observable of text change events for {@code view}. * <p> * <em>Warning:</em> Values emitted by this observable contain a <b>mutable</b> * {@link CharSequence} owned by the host {@code TextView} and thus are <b>not safe</b> to cache * or delay reading (such as by observing on a different thread). If you want to cache or delay * reading the items emitted then you must map values through a function which calls * {@link String#valueOf} or {@link CharSequence#toString() .toString()} to create a copy. * <p> * <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe * to free this reference. * <p> * <em>Note:</em> A value will be emitted immediately on subscribe. */ @CheckResult @NonNull public static InitialValueObservable<TextViewTextChangeEvent> textChangeEvents( @NonNull TextView view) { checkNotNull(view, "view == null"); return new TextViewTextChangeEventObservable(view); } /** * Create an observable of before text change events for {@code view}. * <p> * <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe * to free this reference. * <p> * <em>Note:</em> A value will be emitted immediately on subscribe. */ @CheckResult @NonNull public static InitialValueObservable<TextViewBeforeTextChangeEvent> beforeTextChangeEvents( @NonNull TextView view) { checkNotNull(view, "view == null"); return new TextViewBeforeTextChangeEventObservable(view); } /** * Create an observable of after text change events for {@code view}. * <p> * <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe * to free this reference. * <p> * <em>Note:</em> A value will be emitted immediately on subscribe using * {@link TextView#getEditableText()}. */ @CheckResult @NonNull public static InitialValueObservable<TextViewAfterTextChangeEvent> afterTextChangeEvents( @NonNull TextView view) { checkNotNull(view, "view == null"); return new TextViewAfterTextChangeEventObservable(view); } /** * An action which sets the text property of {@code view} with character sequences. * <p> * <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe * to free this reference. */ @CheckResult @NonNull public static Consumer<? super CharSequence> text(@NonNull final TextView view) { checkNotNull(view, "view == null"); return new Consumer<CharSequence>() { @Override public void accept(CharSequence text) { view.setText(text); } }; } /** * An action which sets the text property of {@code view} string resource IDs. * <p> * <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe * to free this reference. */ @CheckResult @NonNull public static Consumer<? super Integer> textRes(@NonNull final TextView view) { checkNotNull(view, "view == null"); return new Consumer<Integer>() { @Override public void accept(Integer textRes) { view.setText(textRes); } }; } /** * An action which sets the error property of {@code view} with character sequences. * <p> * <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe * to free this reference. */ @CheckResult @NonNull public static Consumer<? super CharSequence> error(@NonNull final TextView view) { checkNotNull(view, "view == null"); return new Consumer<CharSequence>() { @Override public void accept(CharSequence text) { view.setError(text); } }; } /** * An action which sets the error property of {@code view} string resource IDs. * <p> * <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe * to free this reference. */ @CheckResult @NonNull public static Consumer<? super Integer> errorRes(@NonNull final TextView view) { checkNotNull(view, "view == null"); return new Consumer<Integer>() { @Override public void accept(Integer textRes) { view.setError(view.getContext().getResources().getText(textRes)); } }; } /** * An action which sets the hint property of {@code view} with character sequences. * <p> * <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe * to free this reference. */ @CheckResult @NonNull public static Consumer<? super CharSequence> hint(@NonNull final TextView view) { checkNotNull(view, "view == null"); return new Consumer<CharSequence>() { @Override public void accept(CharSequence hint) { view.setHint(hint); } }; } /** * An action which sets the hint property of {@code view} string resource IDs. * <p> * <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe * to free this reference. */ @CheckResult @NonNull public static Consumer<? super Integer> hintRes(@NonNull final TextView view) { checkNotNull(view, "view == null"); return new Consumer<Integer>() { @Override public void accept(Integer hintRes) { view.setHint(hintRes); } }; } /** * An action which sets the color property of {@code view} with color integer. * <p> * <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe * to free this reference. */ @CheckResult @NonNull public static Consumer<? super Integer> color(@NonNull final TextView view) { checkNotNull(view, "view == null"); return new Consumer<Integer>() { @Override public void accept(Integer color) throws Exception { view.setTextColor(color); } }; } private RxTextView() { throw new AssertionError("No instances."); } }