📜  使用 RxJava 运算符实现搜索

📅  最后修改于: 2022-05-13 01:58:44.651000             🧑  作者: Mango

使用 RxJava 运算符实现搜索

如今,我们在日常生活中使用的大多数程序都包含一个搜索选项,使我们能够轻松找到我们正在寻找的内容。因此,拥有搜索工具至关重要。作为开发人员,我们的工作就是更好地实现它。让我们看看如何使用 RxJava Operators 做得更好。

图 1. GfG 中的 RxSearch。

以下 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 来救援。它只返回最近搜索查询的结果并忽略其他查询。

结论

是的,这篇文章就差不多了,通过这个你现在可以使用 RxJava 实现一个 RxSearch,这个搜索在很多地方都使用,比如 Netflix、谷歌,甚至 Geeks for Geeks。想象一下没有 Rx 的世界会有多艰难!