【问题标题】:how to implement search viewmodel and show it in recyclerview in kotlin如何实现搜索视图模型并将其显示在 kotlin 的 recyclerview 中
【发布时间】:2021-07-19 08:07:42
【问题描述】:

我正在开发电视节目应用程序,我正在实现以下逻辑用户搜索电视节目,过滤结果必须显示在 recyclerview 中,但我想在视图模型中实现过滤功能

我怎样才能做到这一点

接口类下面

interface ApiInterface {

    @GET("search/shows")
    suspend fun searchShows( @Query("q") query: String): Call<TvMazeResponse>

}

在 TvRepository.kt 下方

class TvRepository(private val apiInterface: ApiInterface) {


suspend fun getShows() = apiInterface.searchShows("")

}

在适配器类下面

class TvAdapter : RecyclerView.Adapter<TvAdapter.ViewHolder>(), Filterable {

    lateinit var tvMazeList: MutableList<TvMazeResponse>
    lateinit var filterResult: ArrayList<TvMazeResponse>


    override fun getItemCount(): Int =
        filterResult.size


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
        LayoutInflater.from(parent.context).inflate(
            R.layout.tv_item, parent,
            false
        )
    )

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bind(filterResult[position])
    }


    fun addData(list: List<TvMazeResponse>) {
        tvMazeList = list as MutableList<TvMazeResponse>
        filterResult = tvMazeList as ArrayList<TvMazeResponse>
        notifyDataSetChanged()
    }

    override fun getFilter(): Filter {
        return object : Filter() {
            override fun performFiltering(constraint: CharSequence?): FilterResults {
                val charString = constraint?.toString() ?: ""
                if (charString.isEmpty()) filterResult =
                    tvMazeList as ArrayList<TvMazeResponse> else {
                    val filteredList = ArrayList<TvMazeResponse>()
                    tvMazeList
                        .filter {
                            (it.name.contains(constraint!!)) or
                                    (it.language.contains(constraint))

                        }
                        .forEach { filteredList.add(it) }
                    filterResult = filteredList

                }

                return FilterResults().apply { values = filterResult }
            }

            override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
                filterResult = if (results?.values == null)
                    ArrayList()
                else
                    results.values as ArrayList<TvMazeResponse>
                notifyDataSetChanged()
            }

        }
    }


    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        fun bind(result: TvMazeResponse) {
            with(itemView) {
                Picasso.get().load(result.image.medium).into(imageView)
            }
        }
    }


}

在常量.kt 下

object Constants {
    const val BASE_URL = "https://api.tvmaze.com/"
}

在 TvMazeResponse.kt 下方

data class TvMazeResponse(
    @SerializedName("averageRuntime")
    val averageRuntime: Int,
    @SerializedName("dvdCountry")
    val dvdCountry: Any,
    @SerializedName("externals")
    val externals: Externals,
    @SerializedName("genres")
    val genres: List<String>,
    @SerializedName("id")
    val id: Int,
    @SerializedName("image")
    val image: Image,
    @SerializedName("language")
    val language: String,
    @SerializedName("_links")
    val links: Links,
    @SerializedName("name")
    val name: String,
    @SerializedName("network")
    val network: Network,
    @SerializedName("officialSite")
    val officialSite: String,
    @SerializedName("premiered")
    val premiered: String,
    @SerializedName("rating")
    val rating: Rating,
    @SerializedName("runtime")
    val runtime: Int,
    @SerializedName("schedule")
    val schedule: Schedule,
    @SerializedName("status")
    val status: String,
    @SerializedName("summary")
    val summary: String,
    @SerializedName("type")
    val type: String,
    @SerializedName("updated")
    val updated: Int,
    @SerializedName("url")
    val url: String,
    @SerializedName("webChannel")
    val webChannel: Any,
    @SerializedName("weight")
    val weight: Int
)

在 TvViewModel.kt 下

class TvViewModel(apiInterface: ApiInterface) : ViewModel() {




}

我想在 viewmodel 中实现过滤和搜索功能,我该如何实现,非常感谢任何帮助和提示

【问题讨论】:

  • 如果您的 api 接受 searchkeyword 则不要在适配器上应用填充器,使用 Diffutil 更新列表和新的数据响应。
  • @UmashYadav 如何在 viewmodel 中实现该逻辑,您能用编码示例解释一下吗
  • 您的回答与此无关我需要在 viewmodel 中实现搜索和过滤功能并在 recyclerview 中显示
  • 上传完整代码是指Activity.kt,viewmodel.kt,repository.kt,adapter.kt,api相关类
  • 你的意思是我必须上传我的所有代码

标签: android viewmodel kotlin-coroutines android-filter


【解决方案1】:

在 TvRepository 中将 getShows 函数更改为

suspend fun getShows(searchString:String) = apiInterface.searchShows(searchString)

然后在 ViewModel 中更改构造函数以获取 TVRepository 的实例并调用 API,如下所示

class TvViewModel( tvRepository: TvRepository) : ViewModel() {

 fun getShows(searchParameter:String){
   viewModelScope.launch(Dispatchers.IO){
     val response= tvRepository.getShows().awaitResponse()
     if(response.isSuccessful{
       //api success you can get result from response.body

     }
     else{
       //api failed
     }
   }
}



}

【讨论】:

  • dhiraj uchil 非常感谢您的回答,可以在 viewmodel 中实现搜索功能,有人建议我实现 debounce 运算符
  • 上面的代码在ViewModel里面,你到底想在viewmodel里面做什么?
  • 我想在 viewmodel 中实现搜索功能,用户类型显示名称,结果必须显示在 recyclerview 中
  • @dhirajuchul 你理解任务了吗
猜你喜欢
  • 2020-04-01
  • 2020-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-22
相关资源
最近更新 更多