Skip to content

Add SearchView observables #213

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.jakewharton.rxbinding.support.v7.widget

import android.support.v7.widget.SearchView
import com.jakewharton.rxbinding.internal.Functions
import rx.Observable
import rx.functions.Action1
import rx.functions.Func1

/**
* Create an observable of {@linkplain SearchViewQueryTextEvent query text events} on {@code
Expand Down Expand Up @@ -34,3 +36,37 @@ public inline fun SearchView.queryTextChanges(): Observable<CharSequence> = RxSe
* @param submit weather to submit query right after updating query text
*/
public inline fun SearchView.query(submit: Boolean): Action1<in CharSequence> = RxSearchView.query(this, submit)

/**
* Create an observable of booleans representing the focus of the query text field.
*
* *Warning:* The created observable keeps a strong reference to `view`. Unsubscribe
* to free this reference.
*
*/
public inline fun SearchView.queryTextFocusChange(): Observable<Boolean> = RxSearchView.queryTextFocusChange(this)

/**
* Create an observable of the absolute position of the clicked item in the list of suggestions
*
* *Warning:* The created observable keeps a strong reference to `view`. Unsubscribe
* to free this reference.
*
* *Warning:* The created observable uses [SearchView.setOnSuggestionListener] to
* observe search view events. Only one observable can be used for a search view at a time.
*/
public inline fun SearchView.suggestionClick(): Observable<Int> = RxSearchView.suggestionClick(this)

/**
* Create an observable of the absolute position of the clicked item in the list of suggestions
*
* *Warning:* The created observable keeps a strong reference to `view`. Unsubscribe
* to free this reference.
*
* *Warning:* The created observable uses [SearchView.setOnSuggestionListener] to
* observe search view events. Only one observable can be used for a search view at a time.
*
* @param handled Function invoked with each value to determine the return value of the
* underlying [SearchView.OnSuggestionListener].
*/
public inline fun SearchView.suggestionClick(handled: Func1<in Int, Boolean>): Observable<Int> = RxSearchView.suggestionClick(this, handled)
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import android.support.v7.widget.SearchView;

import com.jakewharton.rxbinding.internal.Functions;

import rx.Observable;
import rx.functions.Action1;
import rx.functions.Func1;

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

Expand Down Expand Up @@ -62,6 +66,55 @@ public static Action1<? super CharSequence> query(@NonNull final SearchView view
};
}

/**
* Create an observable of booleans representing the focus of the query text field.
* <p>
* <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe
* to free this reference.
* <p>
*/
@CheckResult @NonNull
public static Observable<Boolean> queryTextFocusChange(@NonNull SearchView view) {
checkNotNull(view, "view == null");
return Observable.create(new SearchViewQueryTextFocusChangeOnSubscribe(view));
}

/**
* Create an observable of the absolute position of the clicked item in the list of suggestions
* <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 SearchView#setOnSuggestionListener} to
* observe search view events. Only one observable can be used for a search view at a time.
*/
@CheckResult @NonNull
public static Observable<Integer> suggestionClick(@NonNull SearchView view) {
checkNotNull(view, "view == null");
return Observable.create(new SearchViewSuggestionClickOnSubscribe(view,
Functions.FUNC1_ALWAYS_TRUE));
}

/**
* Create an observable of the absolute position of the clicked item in the list of suggestions
* <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 SearchView#setOnSuggestionListener} to
* observe search view events. Only one observable can be used for a search view at a time.
*
* @param handled Function invoked with each value to determine the return value of the
* underlying {@link SearchView.OnSuggestionListener}.
*/
@CheckResult @NonNull
public static Observable<Integer> suggestionClick(@NonNull SearchView view,
@NonNull Func1<? super Integer, Boolean> handled) {
checkNotNull(view, "view == null");
checkNotNull(handled, "handled == null");
return Observable.create(new SearchViewSuggestionClickOnSubscribe(view, handled));
}

private RxSearchView() {
throw new AssertionError("No instances.");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.jakewharton.rxbinding.support.v7.widget;

import android.support.v7.widget.SearchView;
import android.view.View;

import rx.Observable;
import rx.Subscriber;
import rx.android.MainThreadSubscription;

final class SearchViewQueryTextFocusChangeOnSubscribe
implements Observable.OnSubscribe<Boolean> {
final SearchView view;

SearchViewQueryTextFocusChangeOnSubscribe(SearchView view) {
this.view = view;
}

@Override public void call(final Subscriber<? super Boolean> subscriber) {
View.OnFocusChangeListener onFocusChangeListener = new View.OnFocusChangeListener() {
@Override public void onFocusChange(View v, boolean hasFocus) {
if (!subscriber.isUnsubscribed()) {
subscriber.onNext(hasFocus);
}
}
};

view.setOnQueryTextFocusChangeListener(onFocusChangeListener);

subscriber.add(new MainThreadSubscription() {
@Override protected void onUnsubscribe() {
view.setOnQueryTextFocusChangeListener(null);
}
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.jakewharton.rxbinding.support.v7.widget;

import android.support.v7.widget.SearchView;

import rx.Observable;
import rx.Subscriber;
import rx.android.MainThreadSubscription;
import rx.functions.Func1;

final class SearchViewSuggestionClickOnSubscribe
implements Observable.OnSubscribe<Integer> {
final SearchView view;
final Func1<? super Integer, Boolean> handled;

SearchViewSuggestionClickOnSubscribe(SearchView view,
Func1<? super Integer, Boolean> handled) {
this.view = view;
this.handled = handled;
}

@Override public void call(final Subscriber<? super Integer> subscriber) {
SearchView.OnSuggestionListener listener = new SearchView.OnSuggestionListener() {
@Override public boolean onSuggestionSelect(int position) {
return false;
}

@Override public boolean onSuggestionClick(int position) {
if (handled.call(position)) {
if (!subscriber.isUnsubscribed()) {
subscriber.onNext(position);
}
return true;
}
return false;
}
};

view.setOnSuggestionListener(listener);

subscriber.add(new MainThreadSubscription() {
@Override protected void onUnsubscribe() {
view.setOnSuggestionListener(null);
}
});
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.jakewharton.rxbinding.widget

import android.widget.SearchView
import com.jakewharton.rxbinding.internal.Functions
import rx.Observable
import rx.functions.Action1
import rx.functions.Func1

/**
* Create an observable of {@linkplain SearchViewQueryTextEvent query text events} on {@code
Expand Down Expand Up @@ -34,3 +36,37 @@ public inline fun SearchView.queryTextChanges(): Observable<CharSequence> = RxSe
* @param submit weather to submit query right after updating query text
*/
public inline fun SearchView.query(submit: Boolean): Action1<in CharSequence> = RxSearchView.query(this, submit)

/**
* Create an observable of booleans representing the focus of the query text field.
*
* *Warning:* The created observable keeps a strong reference to `view`. Unsubscribe
* to free this reference.
*
*/
public inline fun SearchView.queryTextFocusChange(): Observable<Boolean> = RxSearchView.queryTextFocusChange(this)

/**
* Create an observable of the absolute position of the clicked item in the list of suggestions
*
* *Warning:* The created observable keeps a strong reference to `view`. Unsubscribe
* to free this reference.
*
* *Warning:* The created observable uses [SearchView.setOnSuggestionListener] to
* observe search view events. Only one observable can be used for a search view at a time.
*/
public inline fun SearchView.suggestionClick(): Observable<Int> = RxSearchView.suggestionClick(this)

/**
* Create an observable of the absolute position of the clicked item in the list of suggestions
*
* *Warning:* The created observable keeps a strong reference to `view`. Unsubscribe
* to free this reference.
*
* *Warning:* The created observable uses [SearchView.setOnSuggestionListener] to
* observe search view events. Only one observable can be used for a search view at a time.
*
* @param handled Function invoked with each value to determine the return value of the
* underlying [SearchView.OnSuggestionListener].
*/
public inline fun SearchView.suggestionClick(handled: Func1<in Int, Boolean>): Observable<Int> = RxSearchView.suggestionClick(this, handled)
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import android.widget.SearchView;

import com.jakewharton.rxbinding.internal.Functions;

import rx.Observable;
import rx.functions.Action1;
import rx.functions.Func1;

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

Expand Down Expand Up @@ -62,6 +66,55 @@ public static Action1<? super CharSequence> query(@NonNull final SearchView view
};
}

/**
* Create an observable of booleans representing the focus of the query text field.
* <p>
* <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe
* to free this reference.
* <p>
*/
@CheckResult @NonNull
public static Observable<Boolean> queryTextFocusChange(@NonNull SearchView view) {
checkNotNull(view, "view == null");
return Observable.create(new SearchViewQueryTextFocusChangeOnSubscribe(view));
}

/**
* Create an observable of the absolute position of the clicked item in the list of suggestions
* <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 SearchView#setOnSuggestionListener} to
* observe search view events. Only one observable can be used for a search view at a time.
*/
@CheckResult @NonNull
public static Observable<Integer> suggestionClick(@NonNull SearchView view) {
checkNotNull(view, "view == null");
return Observable.create(new SearchViewSuggestionClickOnSubscribe(view,
Functions.FUNC1_ALWAYS_TRUE));
}

/**
* Create an observable of the absolute position of the clicked item in the list of suggestions
* <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 SearchView#setOnSuggestionListener} to
* observe search view events. Only one observable can be used for a search view at a time.
*
* @param handled Function invoked with each value to determine the return value of the
* underlying {@link SearchView.OnSuggestionListener}.
*/
@CheckResult @NonNull
public static Observable<Integer> suggestionClick(@NonNull SearchView view,
@NonNull Func1<? super Integer, Boolean> handled) {
checkNotNull(view, "view == null");
checkNotNull(handled, "handled == null");
return Observable.create(new SearchViewSuggestionClickOnSubscribe(view, handled));
}

private RxSearchView() {
throw new AssertionError("No instances.");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.jakewharton.rxbinding.widget;

import android.view.View;
import android.widget.SearchView;

import rx.Observable;
import rx.Subscriber;
import rx.android.MainThreadSubscription;

final class SearchViewQueryTextFocusChangeOnSubscribe
implements Observable.OnSubscribe<Boolean> {
final SearchView view;

SearchViewQueryTextFocusChangeOnSubscribe(SearchView view) {
this.view = view;
}

@Override public void call(final Subscriber<? super Boolean> subscriber) {
View.OnFocusChangeListener onFocusChangeListener = new View.OnFocusChangeListener() {
@Override public void onFocusChange(View v, boolean hasFocus) {
if (!subscriber.isUnsubscribed()) {
subscriber.onNext(hasFocus);
}
}
};

view.setOnQueryTextFocusChangeListener(onFocusChangeListener);

subscriber.add(new MainThreadSubscription() {
@Override protected void onUnsubscribe() {
view.setOnQueryTextFocusChangeListener(null);
}
});
}
}
Loading