使用 RxJava 运算符实现搜索
如今,我们在日常生活中使用的大多数程序都包含一个搜索选项,使我们能够轻松找到我们正在寻找的内容。因此,拥有搜索工具至关重要。作为开发人员,我们的工作就是更好地实现它。让我们看看如何使用 RxJava Operators 做得更好。
以下 RxJava 功能将用于构建此搜索功能:
先决条件:我们需要了解基本的 RxJava 函数,因为实现搜索有点高阶。
- 运算符过滤器
- 操作员去抖
- DistinctUntilChanged 运算符
- SwitchMap 的操作符
哇!虽然这听起来像实施搜索真的很困难,但不。当我们按照本文下文所述逐步执行时,这真的很容易,您将立即启动并运行。此外,以上所有术语都链接到其他很棒的 GfG 文章,以扩展您的学习!事不宜迟,让我们开始吧。
分步实施
步骤#1:使搜索视图可观察
首先,您必须使 SearchView 可见。让我们使用 PublishSubject 使 SearchView 可观察。在这里,我们正在使用 Android SearchView。视图可能是任何看起来像 EditText 的东西。只是您需要构建文本更改侦听器以使该视图可见。
Java
public class GfGSearch {
public static Observable fromView(SearchView gfgSearch) {
final gfgArticle article = gfgArticle.create();
gfgSearch.setOnQueryTextListener(new gfgSearch.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
article.onComplete();
return true;
}
@Override
public boolean onQueryTextChange(String text) {
article.onNext(text);
return true;
}
});
return article;
}
}
Java
@Override
public ObservableSource apply(String query)
{
return dataFromNetwork(query)
.doOnError(throwable
-> {
// Exception Handling
})
.onErrorReturn(throwable -> "");
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer() {
@Override public void accept(String result)
{
searchResult.setText(result);
}
});
RxGfGSearch.fromView(searchView)
.debounce(200, TimeUnit.MILLISECONDS)
.filter(new Predicate() {
@Override public boolean test(String text)
{
if (text.isEmpty()) {
searchResult.setText("Spandan");
return false;
}
else {
return true;
}
}
})
.distinctUntilChanged()
.switchMap(new Function >() {
步骤 #2:应用运算符
您必须对该 SearchView observable 使用以下操作:
Java
@Override
public ObservableSource apply(String query)
{
return dataFromNetwork(query)
.doOnError(throwable
-> {
// Exception Handling
})
.onErrorReturn(throwable -> "");
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer() {
@Override public void accept(String result)
{
searchResult.setText(result);
}
});
RxGfGSearch.fromView(searchView)
.debounce(200, TimeUnit.MILLISECONDS)
.filter(new Predicate() {
@Override public boolean test(String text)
{
if (text.isEmpty()) {
searchResult.setText("Spandan");
return false;
}
else {
return true;
}
}
})
.distinctUntilChanged()
.switchMap(new Function >() {
了解我们在上述代码中使用的术语:
DistinctUntilChanged: distinctUntilChanged运算符可防止重复的网络调用。假设最近正在进行的搜索查询是“abc”,并且用户在再次输入“c”之前删除了“c”。所以它又是“abc”。因此,如果网络调用已经在使用搜索查询“abc”进行,它将不会使用搜索查询“abc”发起重复调用。结果, distinctUntilChanged 防止源 Observable 发出重复的连续项。
- 过滤器:过滤器运算符用于过滤掉不需要的字符串,例如本例中的空字符串,以避免进行不必要的网络调用。
- Debounce :在这种情况下,使用 debounce运算符具有时间常数。当用户在短时间内输入“a”、“ab”或“abc”时,去抖动运算符会处理这种情况。结果,将有过多的网络调用。然而,用户最终对搜索“abc”的结果感兴趣。结果,“a”和“ab”的结果必须被丢弃。理想情况下,没有网络需要“a”和“ab”,因为用户在很短的时间内就写好了这些。结果,去抖运算符介入帮助。如果在这段时间之间有另一个搜索查询到达,则去抖动将丢弃旧项目并使用新的搜索查询再次开始等待该时间。如果在该恒定时间段内没有新的到达,它将返回到该搜索查询以进行额外处理。因此,debounce 只会在某个时间跨度过去而没有发射另一个项目的情况下从 Observable 发射一个项目。
- SwitchMap : switchMap运算符在这里用于防止不再需要向用户显示的网络调用结果。假设最近的搜索查询是“ab”,有一个对“ab”的活动网络调用,并且用户输入了“abc”。那么你就不再对“ab”的结果感兴趣了。您只关心“abc”的结果。因此,switchMap 来救援。它只返回最近搜索查询的结果并忽略其他查询。
Geek Tip #1: Returns a new Observable by applying the given function to each item emitted by the source.
结论
是的,这篇文章就差不多了,通过这个你现在可以使用 RxJava 实现一个 RxSearch,这个搜索在很多地方都使用,比如 Netflix、谷歌,甚至 Geeks for Geeks。想象一下没有 Rx 的世界会有多艰难!
Always Remember:
There is something for everything in RxJava!