I am developing tvshows app where I am implementing following logic user search tvshows and filtered result has to show in recyclerview but I want to implement filtering functionality in viewmodel
how can I achieve that
below interface class
interface ApiInterface {
@GET("search/shows")
suspend fun searchShows( @Query("q") query: String): Call<TvMazeResponse>
}
below TvRepository.kt
class TvRepository(private val apiInterface: ApiInterface) {
suspend fun getShows() = apiInterface.searchShows("")
}
below adapter 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)
}
}
}
}
below Constants.kt
object Constants {
const val BASE_URL = "https://api.tvmaze.com/"
}
below 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
)
below TvViewModel.kt
class TvViewModel(apiInterface: ApiInterface) : ViewModel() {
}
I want to implement filter and search function in viewmodel how can I achieve that any help and tips greatly appreciated
In TvRepository change the getShows function to
Then in the ViewModel change the constructor to get an instance of the TVRepository and call API as shown below