@@ -2,42 +2,92 @@ package com.intive.tmdbandroid.search.ui.adapters
22
33import android.view.LayoutInflater
44import android.view.ViewGroup
5- import androidx.paging.PagingDataAdapter
5+ import androidx.paging.AsyncPagingDataDiffer
6+ import androidx.paging.PagingData
7+ import androidx.recyclerview.widget.AdapterListUpdateCallback
68import androidx.recyclerview.widget.DiffUtil
9+ import androidx.recyclerview.widget.ListUpdateCallback
710import androidx.recyclerview.widget.RecyclerView
811import com.bumptech.glide.Glide
912import com.bumptech.glide.request.RequestOptions
1013import com.intive.tmdbandroid.R
14+ import com.intive.tmdbandroid.databinding.HeaderResultsSearchBinding
1115import com.intive.tmdbandroid.databinding.ItemFoundSearchBinding
1216import com.intive.tmdbandroid.model.TVShow
1317import timber.log.Timber
1418import java.lang.Exception
1519import java.time.LocalDate
1620import java.time.format.DateTimeFormatter
1721
18- class TVShowSearchAdapter () : PagingDataAdapter<TVShow, TVShowSearchAdapter.SearchResultHolder>(REPO_COMPARATOR ) {
22+ class TVShowSearchAdapter (private val clickListener : ((TVShow ) -> Unit )) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
23+ var query: String = " "
24+
25+ val adapterCallback = AdapterListUpdateCallback (this )
26+
1927 companion object {
20- private val REPO_COMPARATOR = object : DiffUtil .ItemCallback <TVShow >() {
21- override fun areItemsTheSame (oldItem : TVShow , newItem : TVShow ): Boolean = (oldItem == newItem)
22- override fun areContentsTheSame (oldItem : TVShow , newItem : TVShow ): Boolean = (oldItem == newItem)
28+ private const val HEADER = 0
29+ private const val ITEM = 1
2330 }
24- }
25- var query: String = " "
2631
27- var clickListener: ((TVShow ) -> Unit )? = null
32+ val differ = AsyncPagingDataDiffer (
33+ TVShowAsyncPagingDataDiffCallback (),
34+ object : ListUpdateCallback {
35+ override fun onInserted (position : Int , count : Int ) {
36+ adapterCallback.onInserted(position + 1 , count)
37+ }
38+
39+ override fun onRemoved (position : Int , count : Int ) {
40+ adapterCallback.onRemoved(position + 1 , count)
41+ }
42+
43+ override fun onMoved (fromPosition : Int , toPosition : Int ) {
44+ adapterCallback.onMoved(fromPosition + 1 , toPosition + 1 )
45+ }
46+
47+ override fun onChanged (position : Int , count : Int , payload : Any? ) {
48+ adapterCallback.onChanged(position + 1 , count, payload)
49+ }
50+
51+ }
52+ )
53+
54+ suspend fun submitData (tvShowPagingData : PagingData <TVShow >) {
55+ differ.submitData(tvShowPagingData)
56+ }
2857
29- override fun onCreateViewHolder ( parent : ViewGroup , viewType : Int ): TVShowSearchAdapter . SearchResultHolder {
30- val resultHolder = ItemFoundSearchBinding .inflate( LayoutInflater .from(parent.context), parent, false )
31- return SearchResultHolder (resultHolder)
58+ override fun getItemCount ( ): Int {
59+ return differ.itemCount + 1
60+ }
3261
62+ override fun getItemViewType (position : Int ): Int {
63+ return when (position) {
64+ 0 -> HEADER
65+ else -> ITEM
66+ }
3367 }
3468
35- override fun onBindViewHolder (holder : TVShowSearchAdapter .SearchResultHolder , position : Int ) {
36- val tvShowItem = getItem(position) as TVShow
37- holder.bind(tvShowItem)
69+ override fun onCreateViewHolder (parent : ViewGroup , viewType : Int ): RecyclerView .ViewHolder {
70+ return when (viewType) {
71+ HEADER -> HeaderHolder (HeaderResultsSearchBinding .inflate(LayoutInflater .from(parent.context), parent, false ))
72+ ITEM -> SearchResultHolder (ItemFoundSearchBinding .inflate(LayoutInflater .from(parent.context), parent, false ), clickListener)
73+ else -> throw Exception (" Illegal ViewType" )
74+ }
3875 }
3976
40- inner class SearchResultHolder (val binding : ItemFoundSearchBinding ) : RecyclerView.ViewHolder(binding.root){
77+ override fun onBindViewHolder (holder : RecyclerView .ViewHolder , position : Int ) {
78+ when (holder) {
79+ is HeaderHolder -> holder.bind(query)
80+ is SearchResultHolder -> differ.getItem(position - 1 )?.let { holder.bind(it) }
81+ }
82+ }
83+
84+ inner class HeaderHolder (private val binding : HeaderResultsSearchBinding ): RecyclerView.ViewHolder(binding.root){
85+ fun bind (query : String ){
86+ binding.searchHeader.text = binding.root.context.getString(R .string.search_result_header, query)
87+ }
88+ }
89+
90+ inner class SearchResultHolder (private val binding : ItemFoundSearchBinding , private val clickListener : ((TVShow ) -> Unit )) : RecyclerView.ViewHolder(binding.root){
4191
4292 private val itemTitle = binding.itemTitleSearch
4393 private val itemYear = binding.itemYearSearch
@@ -47,7 +97,7 @@ class TVShowSearchAdapter() : PagingDataAdapter<TVShow, TVShowSearchAdapter.Sear
4797 fun bind (item : TVShow ){
4898
4999 itemView.setOnClickListener {
50- clickListener? .invoke(item)
100+ clickListener.invoke(item)
51101 }
52102
53103 try {
@@ -87,4 +137,14 @@ class TVShowSearchAdapter() : PagingDataAdapter<TVShow, TVShowSearchAdapter.Sear
87137 }
88138 }
89139
140+ private class TVShowAsyncPagingDataDiffCallback : DiffUtil .ItemCallback <TVShow >() {
141+ override fun areItemsTheSame (oldItem : TVShow , newItem : TVShow ): Boolean {
142+ return oldItem.id == newItem.id
143+ }
144+
145+ override fun areContentsTheSame (oldItem : TVShow , newItem : TVShow ): Boolean {
146+ return oldItem == newItem
147+ }
148+ }
149+
90150}
0 commit comments