如何在 kotlin 中实现搜索视图模型并在 recyclerview 中显示它
how to implement search viewmodel and show it in recyclerview in kotlin
我正在开发电视节目应用程序,我正在执行以下逻辑用户搜索电视节目并且过滤结果必须显示在 recyclerview 中,但我想在 viewmodel 中实现过滤功能
我怎样才能做到这一点
界面下方class
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
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)
}
}
}
}
低于Constants.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 中实现过滤和搜索功能,我该如何实现,非常感谢任何帮助和提示
在 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
}
}
}
}
我正在开发电视节目应用程序,我正在执行以下逻辑用户搜索电视节目并且过滤结果必须显示在 recyclerview 中,但我想在 viewmodel 中实现过滤功能
我怎样才能做到这一点
界面下方class
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
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)
}
}
}
}
低于Constants.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 中实现过滤和搜索功能,我该如何实现,非常感谢任何帮助和提示
在 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
}
}
}
}