实现android(网络)搜索

实现android(网络)搜索,android,search,searchview,searchable,Android,Search,Searchview,Searchable,我迷路了 在过去的几天里,我一直在努力了解在我的Android应用程序中实现网络搜索的最佳方式是什么 我想保留MVVM体系结构,但是如果它要求太多,我已经准备好考虑其他备选方案了。 我需要能够在网页中搜索 一个好的例子\指南将非常感谢 谢谢 使用Android的分页库,您可以完成分页网络搜索,并用结果更新RecyclerView 假设您有一个API,我们可以使用它来调用搜索查询。这将由一个您将实现的工具支持,它将在您滚动时提供新的结果页面 interface MySearchApi {

我迷路了

在过去的几天里,我一直在努力了解在我的Android应用程序中实现网络搜索的最佳方式是什么

我想保留MVVM体系结构,但是如果它要求太多,我已经准备好考虑其他备选方案了。 我需要能够在网页中搜索

一个好的例子\指南将非常感谢


谢谢

使用Android的分页库,您可以完成分页网络搜索,并用结果更新RecyclerView

假设您有一个API,我们可以使用它来调用搜索查询。这将由一个您将实现的工具支持,它将在您滚动时提供新的结果页面

interface MySearchApi {
    fun search(query: String, count: Int): PagedList<SearchResult>
}
接口MySearchApi{
有趣的搜索(查询:字符串,计数:Int):页面列表
}
我们得到的是a,它会随着更多搜索结果的加载而更新。我们没有将其包装在Rx Observable或LiveData对象中,因为在这种情况下,我们不希望加载的数据发生更改。如果您正在查询某个实时服务,该服务可能会在任何时候更改结果,那么您可能需要考虑这一点。 我们可以从ViewModel对象中公开此分页列表或LiveData,并构建PagedListAdapter子类,该子类将在加载新数据时使用新数据更新RecyclerView

class MySearchAdapter() :
        PagedListAdapter<SearchResult, SearchResultViewHolder>(DIFF_CALLBACK) {
    fun onBindViewHolder(holder: SearchResultViewHolder, position: Int) {
        val concert: SearchResult? = getItem(position)

        // Note that "searchResult" is a placeholder if it's null.
        holder.bindTo(searchResult)
    }

    companion object {
        private val DIFF_CALLBACK = object :
                DiffUtil.ItemCallback<Concert>() {
            // Concert details may have changed if reloaded from the database,
            // but ID is fixed.
            override fun areItemsTheSame(oldSearchResult: SearchResult,
                    newSearchResult: SearchResult) = oldSearchResult.id == newSearchResult.id

            override fun areContentsTheSame(oldSearchResult: SearchResult,
                    newSearchResult: Concert) = newSearchResult == newSearchResult
        }
    }
}

类MySearchAdapter():
PagedListAdapter(差异回调){
有趣的BindViewHolder(holder:SearchResultViewHolder,位置:Int){
val concert:SearchResult?=getItem(位置)
//请注意,如果“searchResult”为空,则它是一个占位符。
holder.bindTo(搜索结果)
}
伴星{
private val DIFF_CALLBACK=对象:
DiffUtil.ItemCallback(){
//如果从数据库重新加载,音乐会详细信息可能已更改,
//但身份证是固定的。
覆盖乐趣项相同(旧搜索结果:搜索结果,
newSearchResult:SearchResult)=oldSearchResult.id==newSearchResult.id
覆盖相同的内容(旧的SearchResult:SearchResult,
newSearchResult:Concert)=newSearchResult==newSearchResult
}
}
}
使用RecyclerView将其连接起来,就像您通常使用的任何其他适配器和RecyclerView一样,您的页面列表应该在数据源需要新的数据页面时通知它


您可以阅读有关分页体系结构的更多信息。

这取决于您的API和数据量(以及您的需求)。例如,如果您可以在本地缓存所有数据,因为它大约有20000项,那么您甚至可以从SQLite本地查询并显示这些数据。那就不用打网络电话了,可以脱机工作了。谢谢你,亚历克斯。事实上,我已经有了搜索引擎。我的问题是从搜索类型开始的,我不想对每种类型都进行网络调用,但请稍等片刻,看看用户是否键入了其他字符或已删除。就像RxJave和debounce一样,另一个重要的事情是始终显示列表上的最新结果。debounce将是实现这一点的一个很好的方法。在键入的每个字符上,可以在输入中发出文本。解盎司超时后,您将通知您的模型更改。然后,您可以发出一个新的搜索查询,并用这个新的页面列表替换旧的页面列表(在这种情况下,我将使用前面提到的LiveData>,然后在适当的地方观察它)。对不起,你最初的问题听起来好像你还没有尝试过什么。将来,最好描述一下你到目前为止所做的事情。对此表示歉意。实际上,我的问题是,在向数据源发送输入之前,我不知道如何去抖动。分页库和RxJava之间的集成是我最感兴趣的,因此我认为我们可以将其分为三个部分:去Bounce、更新数据源和显示数据。你可以在虚拟机中进行去噪,也许可以利用publishsubject。更改输入后,通过publishsubject添加完整的输入文本。您可以对其进行解块并订阅,当您获得一个新值时,您可以从API请求一个新的页面列表。然后,您可以更新ViewModel的LiveData,然后更新适配器的实现。你只需要观察这个livedata,比如在活动中,当你得到一个新的值时更新适配器。哇,Alex,非常感谢你这么快的回复。你有没有机会举个例子?