feat(feed): 피드 어댑터와 뷰 테스트를 추가한다
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
package kr.co.vividnext.sodalive.v2.widget.feed
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class FeedAdapter(
|
||||
private val widthMode: FeedWidthMode = FeedWidthMode.FigmaFixed,
|
||||
private val horizontalItemDecorationDp: Int = 0,
|
||||
private val onClickItem: (FeedItem) -> Unit,
|
||||
private val onBindImages: (FeedImageViews, FeedItem) -> Unit = { _, _ -> }
|
||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
|
||||
private val items = mutableListOf<FeedItem>()
|
||||
|
||||
override fun getItemViewType(position: Int): Int = when (items[position].variant) {
|
||||
FeedVariant.Rank -> VIEW_TYPE_RANK
|
||||
FeedVariant.Live -> VIEW_TYPE_LIVE
|
||||
FeedVariant.Content -> VIEW_TYPE_CONTENT
|
||||
FeedVariant.Community -> VIEW_TYPE_COMMUNITY
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
val inflater = LayoutInflater.from(parent.context)
|
||||
return when (viewType) {
|
||||
VIEW_TYPE_RANK -> RankViewHolder(inflater.inflate(R.layout.view_feed_rank, parent, false) as FeedRankView, parent)
|
||||
VIEW_TYPE_LIVE -> LiveViewHolder(inflater.inflate(R.layout.view_feed_live, parent, false) as FeedLiveView, parent)
|
||||
VIEW_TYPE_CONTENT -> ContentViewHolder(inflater.inflate(R.layout.view_feed_content, parent, false) as FeedContentView, parent)
|
||||
VIEW_TYPE_COMMUNITY -> CommunityViewHolder(inflater.inflate(R.layout.view_feed_community, parent, false) as FeedCommunityView, parent)
|
||||
else -> error("Unknown viewType: $viewType")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
when (val item = items[position]) {
|
||||
is FeedItem.Rank -> (holder as RankViewHolder).bind(item)
|
||||
is FeedItem.Live -> (holder as LiveViewHolder).bind(item)
|
||||
is FeedItem.Content -> (holder as ContentViewHolder).bind(item)
|
||||
is FeedItem.Community -> (holder as CommunityViewHolder).bind(item)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = items.size
|
||||
|
||||
fun submitItems(items: List<FeedItem>) {
|
||||
this.items.clear()
|
||||
this.items.addAll(items)
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
private inner class RankViewHolder(
|
||||
private val view: FeedRankView,
|
||||
private val parent: ViewGroup
|
||||
) : RecyclerView.ViewHolder(view) {
|
||||
fun bind(item: FeedItem.Rank) {
|
||||
view.setFeedSize(calculateSize(item.variant, parent))
|
||||
view.bind(item)
|
||||
view.setOnFeedClick(onClickItem)
|
||||
onBindImages(FeedImageViews(primary = view.imageView()), item)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class LiveViewHolder(
|
||||
private val view: FeedLiveView,
|
||||
private val parent: ViewGroup
|
||||
) : RecyclerView.ViewHolder(view) {
|
||||
fun bind(item: FeedItem.Live) {
|
||||
view.setFeedSize(calculateSize(item.variant, parent))
|
||||
view.bind(item)
|
||||
view.setOnFeedClick(onClickItem)
|
||||
onBindImages(FeedImageViews(profile = view.profileImageView()), item)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class ContentViewHolder(
|
||||
private val view: FeedContentView,
|
||||
private val parent: ViewGroup
|
||||
) : RecyclerView.ViewHolder(view) {
|
||||
fun bind(item: FeedItem.Content) {
|
||||
view.setFeedSize(calculateSize(item.variant, parent))
|
||||
view.bind(item)
|
||||
view.setOnFeedClick(onClickItem)
|
||||
onBindImages(FeedImageViews(primary = view.contentImageView(), profile = view.profileImageView()), item)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class CommunityViewHolder(
|
||||
private val view: FeedCommunityView,
|
||||
private val parent: ViewGroup
|
||||
) : RecyclerView.ViewHolder(view) {
|
||||
fun bind(item: FeedItem.Community) {
|
||||
view.setFeedSize(calculateSize(item.variant, parent))
|
||||
view.bind(item)
|
||||
view.setOnFeedClick(onClickItem)
|
||||
onBindImages(FeedImageViews(profile = view.profileImageView()), item)
|
||||
}
|
||||
}
|
||||
|
||||
private fun calculateSize(variant: FeedVariant, parent: ViewGroup): FeedSize {
|
||||
val parentWidthPx = parent.width.takeIf { it > 0 } ?: parent.resources.displayMetrics.widthPixels
|
||||
val availableWidthPx = parentWidthPx - parent.paddingLeft - parent.paddingRight
|
||||
val availableWidthDp = (availableWidthPx / parent.resources.displayMetrics.density).roundToInt()
|
||||
return FeedSize.from(variant, widthMode, availableWidthDp, horizontalItemDecorationDp)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val VIEW_TYPE_RANK = 1
|
||||
private const val VIEW_TYPE_LIVE = 2
|
||||
private const val VIEW_TYPE_CONTENT = 3
|
||||
private const val VIEW_TYPE_COMMUNITY = 4
|
||||
}
|
||||
}
|
||||
|
||||
data class FeedImageViews(
|
||||
val primary: ImageView? = null,
|
||||
val profile: ImageView? = null
|
||||
)
|
||||
Reference in New Issue
Block a user