Created
November 7, 2022 07:59
-
-
Save Wajahat-Jawaid/20689b5fa9377ca37d32f03fe3b623ac to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PostsAdapter( | |
private val posts: List<PostAdapterModel>, | |
private val viewLifecycleOwner: LifecycleOwner, | |
private val viewModel: PostsViewModel, | |
private val clickListener: OnPostClickListener | |
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { | |
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { | |
val inflater = LayoutInflater.from(parent.context) | |
// Deciding whether to inflate the header view or the item view based on the #viewType | |
return if (viewType == PostAdapterModel.TYPE_ITEM) | |
ItemViewHolder(inflater.inflate(R.layout.post_list_fragment_item, parent, false)) | |
else HeaderViewHolder(inflater.inflate(R.layout.post_list_fragment_header, parent, false)) | |
} | |
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { | |
if (posts[position].type == PostAdapterModel.TYPE_ITEM) | |
(holder as ItemViewHolder).bind(position) | |
else | |
(holder as HeaderViewHolder).bind(position) | |
} | |
override fun getItemCount(): Int { | |
return posts.size | |
} | |
override fun getItemViewType(position: Int): Int { | |
return posts[position].type | |
} | |
inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { | |
fun bind(position: Int) { | |
val item = posts[position] as Post | |
itemView.apply { | |
Glide.with(context) | |
.load(item.featuredImage) | |
.diskCacheStrategy(DiskCacheStrategy.RESOURCE) | |
.into(findViewById<ShapeableImageView>(R.id.featured_image)) | |
findViewById<TextView>(R.id.title).text = item.title | |
findViewById<TextView>(R.id.summary).text = item.excerpt.formatHtml() | |
findViewById<TextView>(R.id.author_name).text = item.author.name | |
// Since whenever the view comes on foreground as the result of scrolling up/down, everytime this | |
// bind function gets called. If not placed the following condition, we will end up calling the API | |
// everytime this view comes on foreground. | |
// To avoid this repeated calls, we keep reference of the subscribers count in the [Post] model and | |
// check if we already have set the value for this particular post. This way, we ensure that for a | |
// particular post, repeated call to fetch the subscribers count is never made. | |
if (item.subscribersCount == INVALID_COUNT) { | |
item.author.getUrl().host?.let { host -> | |
getSubscribersCount(itemView, item, host) | |
} | |
} else { | |
// If the subscribers count is already fetched, set from the variable rather than setting from API | |
findViewById<TextView>(R.id.subscribers_count).text = item.subscribersCount.toString() | |
} | |
setOnClickListener { | |
clickListener.onPostClicked(item) | |
} | |
} | |
} | |
private fun getSubscribersCount(itemView: View, post: Post, blogUrl: String) { | |
viewModel.getSubscribersCount(blogUrl).observe(viewLifecycleOwner) { response -> | |
if (response.status == Status.SUCCESS) { | |
response.data?.subscribersCount?.let { count -> | |
post.subscribersCount = count | |
itemView.findViewById<TextView>(R.id.subscribers_count).text = count.toString() | |
} | |
} | |
} | |
} | |
} | |
inner class HeaderViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { | |
fun bind(position: Int) { | |
val item = posts[position] as PostHeader | |
itemView.apply { | |
findViewById<TextView>(R.id.title).text = item.title | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment