feat(home): 홈 추천 섹션 바인딩을 추가한다
This commit is contained in:
@@ -2,14 +2,54 @@ package kr.co.vividnext.sodalive.v2.main
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.base.BaseFragment
|
||||
import kr.co.vividnext.sodalive.databinding.FragmentV2MainHomeBinding
|
||||
import kr.co.vividnext.sodalive.databinding.ViewSectionTitleBinding
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationAiCharacterSection
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationAiCharacterUiModel
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationBannerSection
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationBannerUiModel
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationCheerCreatorSection
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationCreatorUiModel
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationFirstAudioContentSection
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationFirstAudioContentUiModel
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationGenreCreatorGroupUiModel
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationGenreCreatorSection
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationLiveSection
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationLiveUiModel
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationPopularCommunityPostSection
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationRecentlyActiveCreatorSection
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationRecentlyActiveCreatorUiModel
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationRecentDebutCreatorSection
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationUiState
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.RecommendedActivityType
|
||||
import kr.co.vividnext.sodalive.v2.main.home.ui.HomeAiCharacterAdapter
|
||||
import kr.co.vividnext.sodalive.v2.main.home.ui.HomeBannerBinder
|
||||
import kr.co.vividnext.sodalive.v2.main.home.ui.HomeCheerCreatorAdapter
|
||||
import kr.co.vividnext.sodalive.v2.main.home.ui.HomeFirstAudioAdapter
|
||||
import kr.co.vividnext.sodalive.v2.main.home.ui.HomeFollowAllButtonBinder
|
||||
import kr.co.vividnext.sodalive.v2.main.home.ui.HomeGenreCreatorAdapter
|
||||
import kr.co.vividnext.sodalive.v2.main.home.ui.HomeLiveAdapter
|
||||
import kr.co.vividnext.sodalive.v2.main.home.ui.HomeRecentActivityCreatorAdapter
|
||||
import kr.co.vividnext.sodalive.v2.main.home.ui.HomeRecentDebutCreatorAdapter
|
||||
import kr.co.vividnext.sodalive.v2.widget.AudioContentTag
|
||||
import kr.co.vividnext.sodalive.v2.widget.characterchatthumbnail.CharacterChatThumbnailItem
|
||||
|
||||
class HomeMainFragment : BaseFragment<FragmentV2MainHomeBinding>(
|
||||
FragmentV2MainHomeBinding::inflate
|
||||
) {
|
||||
private val liveAdapter = HomeLiveAdapter()
|
||||
private val recentActivityCreatorAdapter = HomeRecentActivityCreatorAdapter()
|
||||
private val recentDebutCreatorAdapter = HomeRecentDebutCreatorAdapter()
|
||||
private val firstAudioAdapter = HomeFirstAudioAdapter()
|
||||
private val aiCharacterAdapter = HomeAiCharacterAdapter()
|
||||
private val genreCreatorAdapter = HomeGenreCreatorAdapter()
|
||||
private val cheerCreatorAdapter = HomeCheerCreatorAdapter()
|
||||
private var bannerBinder: HomeBannerBinder? = null
|
||||
private var onGenreFollowAllClick: (List<Long>) -> Unit = {}
|
||||
private var onCheerFollowAllClick: (List<Long>) -> Unit = {}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
@@ -23,6 +63,99 @@ class HomeMainFragment : BaseFragment<FragmentV2MainHomeBinding>(
|
||||
)
|
||||
binding.textTabBarHome.root.setOnTabSelectedListener { }
|
||||
setUpSectionTitles()
|
||||
setUpRecommendationAdapters()
|
||||
bindHomeRecommendationContent(phase6SampleContent())
|
||||
}
|
||||
|
||||
private fun setUpRecommendationAdapters() {
|
||||
bannerBinder = HomeBannerBinder(binding.rvHomeBanners)
|
||||
binding.rvHomeLives.adapter = liveAdapter
|
||||
binding.rvHomeRecentActivityCreators.adapter = recentActivityCreatorAdapter
|
||||
binding.rvHomeRecentDebutCreators.adapter = recentDebutCreatorAdapter
|
||||
binding.rvHomeFirstAudioContents.adapter = firstAudioAdapter
|
||||
binding.rvHomeAiCharacters.adapter = aiCharacterAdapter
|
||||
binding.rvHomeGenreCreators.apply {
|
||||
layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
|
||||
adapter = genreCreatorAdapter
|
||||
}
|
||||
binding.rvHomeCheerCreators.apply {
|
||||
layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
|
||||
adapter = cheerCreatorAdapter
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindHomeRecommendationContent(content: HomeRecommendationUiState.Content) {
|
||||
bindLiveSection(content.lives)
|
||||
bindBannerSection(content.banners)
|
||||
bindRecentActivitySection(content.recentlyActiveCreators)
|
||||
bindRecentDebutSection(content.recentDebutCreators)
|
||||
bindFirstAudioSection(content.firstAudioContents)
|
||||
bindAiCharacterSection(content.aiCharacters)
|
||||
bindGenreCreatorSection(content.genreCreators)
|
||||
bindCheerCreatorSection(content.cheerCreators)
|
||||
bindPopularCommunitySection(content.popularCommunityPosts)
|
||||
}
|
||||
|
||||
private fun bindLiveSection(section: HomeRecommendationLiveSection) {
|
||||
binding.llHomeLiveSection.visibility = section.items.toSectionVisibility()
|
||||
liveAdapter.submitItems(section.items)
|
||||
}
|
||||
|
||||
private fun bindBannerSection(section: HomeRecommendationBannerSection) {
|
||||
binding.llHomeBannerSection.visibility = section.items.toSectionVisibility()
|
||||
bannerBinder?.bind(section)
|
||||
}
|
||||
|
||||
private fun bindRecentActivitySection(section: HomeRecommendationRecentlyActiveCreatorSection) {
|
||||
binding.llHomeRecentActivitySection.visibility = section.items.toSectionVisibility()
|
||||
recentActivityCreatorAdapter.submitItems(section.items)
|
||||
}
|
||||
|
||||
private fun bindRecentDebutSection(section: HomeRecommendationRecentDebutCreatorSection) {
|
||||
binding.llHomeRecentDebutSection.visibility = section.items.toSectionVisibility()
|
||||
recentDebutCreatorAdapter.submitItems(section.items)
|
||||
}
|
||||
|
||||
private fun bindFirstAudioSection(section: HomeRecommendationFirstAudioContentSection) {
|
||||
binding.llHomeFirstAudioSection.visibility = section.items.toSectionVisibility()
|
||||
firstAudioAdapter.submitItems(section.items)
|
||||
}
|
||||
|
||||
private fun bindAiCharacterSection(section: HomeRecommendationAiCharacterSection) {
|
||||
binding.llHomeAiCharacterSection.visibility = section.items.toSectionVisibility()
|
||||
aiCharacterAdapter.submitItems(section.items)
|
||||
}
|
||||
|
||||
private fun bindGenreCreatorSection(section: HomeRecommendationGenreCreatorSection) {
|
||||
val group = section.groups.firstOrNull { it.creators.isNotEmpty() }
|
||||
binding.llHomeGenreCreatorSection.visibility = if (group == null) View.GONE else View.VISIBLE
|
||||
if (group == null) {
|
||||
genreCreatorAdapter.submitItems(emptyList())
|
||||
return
|
||||
}
|
||||
binding.tvHomeGenreCreatorTitleGenre.text = group.genre
|
||||
genreCreatorAdapter.submitItems(group.creators)
|
||||
HomeFollowAllButtonBinder.bind(
|
||||
view = binding.viewHomeGenreFollowAll.root,
|
||||
creatorIds = group.creators.map { it.creatorId },
|
||||
isFollowCompleted = group.isFollowCompleted,
|
||||
onClick = onGenreFollowAllClick
|
||||
)
|
||||
}
|
||||
|
||||
private fun bindCheerCreatorSection(section: HomeRecommendationCheerCreatorSection) {
|
||||
binding.llHomeCheerCreatorSection.visibility = section.items.toSectionVisibility()
|
||||
cheerCreatorAdapter.submitItems(section.items)
|
||||
HomeFollowAllButtonBinder.bind(
|
||||
view = binding.viewHomeCheerFollowAll.root,
|
||||
creatorIds = section.items.map { it.creatorId },
|
||||
isFollowCompleted = section.isFollowCompleted,
|
||||
onClick = onCheerFollowAllClick
|
||||
)
|
||||
}
|
||||
|
||||
private fun bindPopularCommunitySection(section: HomeRecommendationPopularCommunityPostSection) {
|
||||
binding.llHomePopularCommunitySection.visibility = section.items.toSectionVisibility()
|
||||
}
|
||||
|
||||
private fun setUpSectionTitles() {
|
||||
@@ -56,4 +189,78 @@ class HomeMainFragment : BaseFragment<FragmentV2MainHomeBinding>(
|
||||
tvSectionTitle.setText(titleResId)
|
||||
ivSectionTitleChevron.visibility = if (showMore) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
private fun List<*>.toSectionVisibility(): Int = if (isEmpty()) View.GONE else View.VISIBLE
|
||||
|
||||
private fun phase6SampleContent(): HomeRecommendationUiState.Content = HomeRecommendationUiState.Content(
|
||||
lives = HomeRecommendationLiveSection(
|
||||
listOf(
|
||||
HomeRecommendationLiveUiModel(1L, 101L, null, "오늘 밤 라이브", "소다", "20:00"),
|
||||
HomeRecommendationLiveUiModel(2L, 102L, null, "감성 낭독", "라임", "21:30"),
|
||||
HomeRecommendationLiveUiModel(3L, 103L, null, "신작 토크", "하루", "22:00")
|
||||
)
|
||||
),
|
||||
banners = HomeRecommendationBannerSection(
|
||||
listOf(
|
||||
HomeRecommendationBannerUiModel("sample-banner-1", null, null, null, null),
|
||||
HomeRecommendationBannerUiModel("sample-banner-2", null, null, null, null)
|
||||
)
|
||||
),
|
||||
recentlyActiveCreators = HomeRecommendationRecentlyActiveCreatorSection(
|
||||
listOf(
|
||||
HomeRecommendationRecentlyActiveCreatorUiModel(
|
||||
201L,
|
||||
"베리",
|
||||
null,
|
||||
"LIVE_REPLAY도 라이브 라벨로 표시",
|
||||
RecommendedActivityType.LiveReplay,
|
||||
RecommendedActivityType.LiveReplay.labelResId,
|
||||
"방금"
|
||||
),
|
||||
HomeRecommendationRecentlyActiveCreatorUiModel(202L, "모카", null, "알 수 없는 활동", null, null, "오늘")
|
||||
)
|
||||
),
|
||||
recentDebutCreators = HomeRecommendationRecentDebutCreatorSection(sampleCreators(301L)),
|
||||
firstAudioContents = HomeRecommendationFirstAudioContentSection(
|
||||
listOf(
|
||||
HomeRecommendationFirstAudioContentUiModel(
|
||||
contentId = 401L,
|
||||
creatorId = 301L,
|
||||
creatorNickname = "아린",
|
||||
creatorProfileImage = null,
|
||||
title = "처음 공개하는 오디오",
|
||||
price = 0,
|
||||
coverImage = null,
|
||||
releaseDate = "2026.06.02",
|
||||
tags = setOf(AudioContentTag.First, AudioContentTag.Point, AudioContentTag.Free)
|
||||
)
|
||||
)
|
||||
),
|
||||
aiCharacters = HomeRecommendationAiCharacterSection(
|
||||
listOf(
|
||||
HomeRecommendationAiCharacterUiModel(
|
||||
CharacterChatThumbnailItem(
|
||||
characterId = 501L,
|
||||
imageUrl = "",
|
||||
characterName = "레아",
|
||||
characterDescription = "밤마다 이야기를 들려주는 AI 캐릭터",
|
||||
chatMessageCount = 14000L,
|
||||
hasOriginal = true,
|
||||
originalTitle = "달빛 아래"
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
genreCreators = HomeRecommendationGenreCreatorSection(
|
||||
listOf(HomeRecommendationGenreCreatorGroupUiModel("로맨스", sampleCreators(601L)))
|
||||
),
|
||||
cheerCreators = HomeRecommendationCheerCreatorSection(sampleCreators(701L)),
|
||||
popularCommunityPosts = HomeRecommendationPopularCommunityPostSection(emptyList())
|
||||
)
|
||||
|
||||
private fun sampleCreators(startId: Long): List<HomeRecommendationCreatorUiModel> = listOf(
|
||||
HomeRecommendationCreatorUiModel(startId, "아린", null),
|
||||
HomeRecommendationCreatorUiModel(startId + 1, "유나", null),
|
||||
HomeRecommendationCreatorUiModel(startId + 2, "세이", null)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
package kr.co.vividnext.sodalive.v2.main.home.ui
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.extensions.loadUrl
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationAiCharacterUiModel
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationBannerSection
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationCreatorUiModel
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationFirstAudioContentUiModel
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationLiveUiModel
|
||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationRecentlyActiveCreatorUiModel
|
||||
import kr.co.vividnext.sodalive.v2.widget.AudioContentCardSize
|
||||
import kr.co.vividnext.sodalive.v2.widget.AudioContentCardView
|
||||
import kr.co.vividnext.sodalive.v2.widget.banner.BannerItem
|
||||
import kr.co.vividnext.sodalive.v2.widget.banner.BannerView
|
||||
import kr.co.vividnext.sodalive.v2.widget.characterchatthumbnail.CharacterChatThumbnailItem
|
||||
import kr.co.vividnext.sodalive.v2.widget.characterchatthumbnail.CharacterChatThumbnailView
|
||||
import kr.co.vividnext.sodalive.v2.widget.livethumbnail.LiveThumbnailItem
|
||||
import kr.co.vividnext.sodalive.v2.widget.livethumbnail.LiveThumbnailSimpleView
|
||||
|
||||
class HomeLiveAdapter : RecyclerView.Adapter<HomeLiveAdapter.LiveViewHolder>() {
|
||||
private var items: List<HomeRecommendationLiveUiModel> = emptyList()
|
||||
private var onClick: ((HomeRecommendationLiveUiModel) -> Unit)? = null
|
||||
|
||||
fun submitItems(items: List<HomeRecommendationLiveUiModel>) {
|
||||
this.items = items
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun setOnLiveClick(listener: ((HomeRecommendationLiveUiModel) -> Unit)?) {
|
||||
onClick = listener
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LiveViewHolder {
|
||||
val view = LayoutInflater.from(parent.context).inflate(R.layout.view_live_thumbnail_simple, parent, false)
|
||||
view.layoutParams = RecyclerView.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
).apply { marginEnd = parent.resources.getDimensionPixelSize(R.dimen.spacing_12) }
|
||||
return LiveViewHolder(view as LiveThumbnailSimpleView)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: LiveViewHolder, position: Int) {
|
||||
holder.bind(items[position], onClick)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = items.size
|
||||
|
||||
class LiveViewHolder(
|
||||
private val view: LiveThumbnailSimpleView
|
||||
) : RecyclerView.ViewHolder(view) {
|
||||
fun bind(
|
||||
item: HomeRecommendationLiveUiModel,
|
||||
onClick: ((HomeRecommendationLiveUiModel) -> Unit)?
|
||||
) {
|
||||
val thumbnailItem = LiveThumbnailItem(
|
||||
liveId = item.liveId,
|
||||
creatorId = item.creatorId,
|
||||
imageUrl = item.imageUrl.orEmpty(),
|
||||
title = item.title,
|
||||
creatorName = item.creatorNickname,
|
||||
liveStartTimeText = item.beginDateTime.orEmpty()
|
||||
)
|
||||
view.bind(thumbnailItem)
|
||||
view.imageView().loadUrl(item.imageUrl)
|
||||
view.setOnLiveThumbnailClick(if (onClick == null) null else { _: LiveThumbnailItem -> onClick.invoke(item) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class HomeBannerBinder(
|
||||
private val bannerView: BannerView
|
||||
) {
|
||||
private var sourceItems: List<kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationBannerUiModel> = emptyList()
|
||||
private var onBannerClick: ((kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationBannerUiModel) -> Unit)? = null
|
||||
|
||||
init {
|
||||
bannerView.setOnBindBannerImage { imageView, item -> imageView.loadUrl(item.imageUrl) }
|
||||
bannerView.setOnBannerClickListener { bannerItem ->
|
||||
sourceItems.firstOrNull { it.bannerId == bannerItem.bannerId }?.let { onBannerClick?.invoke(it) }
|
||||
}
|
||||
}
|
||||
|
||||
fun setOnBannerClick(listener: ((kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationBannerUiModel) -> Unit)?) {
|
||||
onBannerClick = listener
|
||||
}
|
||||
|
||||
fun bind(section: HomeRecommendationBannerSection) {
|
||||
sourceItems = section.items
|
||||
bannerView.setItems(
|
||||
section.items.map { item ->
|
||||
BannerItem(
|
||||
bannerId = item.bannerId,
|
||||
imageUrl = item.imageUrl.orEmpty()
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class HomeRecentActivityCreatorAdapter : RecyclerView.Adapter<HomeRecentActivityCreatorAdapter.CreatorViewHolder>() {
|
||||
private var items: List<HomeRecommendationRecentlyActiveCreatorUiModel> = emptyList()
|
||||
|
||||
fun submitItems(items: List<HomeRecommendationRecentlyActiveCreatorUiModel>) {
|
||||
this.items = items
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CreatorViewHolder {
|
||||
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_home_recent_activity_creator, parent, false)
|
||||
view.layoutParams = recyclerItemLayoutParams(parent)
|
||||
return CreatorViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: CreatorViewHolder, position: Int) {
|
||||
holder.bind(items[position])
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = items.size
|
||||
|
||||
class CreatorViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
private val profileImage = itemView.findViewById<ImageView>(R.id.iv_home_recent_activity_creator_profile)
|
||||
private val activityTypeText = itemView.findViewById<TextView>(R.id.tv_home_recent_activity_type)
|
||||
private val titleText = itemView.findViewById<TextView>(R.id.tv_home_recent_activity_title)
|
||||
private val nicknameText = itemView.findViewById<TextView>(R.id.tv_home_recent_activity_nickname)
|
||||
|
||||
fun bind(item: HomeRecommendationRecentlyActiveCreatorUiModel) {
|
||||
profileImage.loadUrl(item.profileImage)
|
||||
item.activityLabelResId?.let { labelResId ->
|
||||
activityTypeText.setText(labelResId)
|
||||
activityTypeText.visibility = View.VISIBLE
|
||||
} ?: run {
|
||||
activityTypeText.visibility = View.GONE
|
||||
}
|
||||
titleText.text = item.activityAt.orEmpty()
|
||||
titleText.visibility = if (item.activityAt.isNullOrBlank()) View.GONE else View.VISIBLE
|
||||
nicknameText.text = item.nickname
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class HomeRecentDebutCreatorAdapter : RecyclerView.Adapter<HomeRecentDebutCreatorAdapter.CreatorViewHolder>() {
|
||||
private var items: List<HomeRecommendationCreatorUiModel> = emptyList()
|
||||
|
||||
fun submitItems(items: List<HomeRecommendationCreatorUiModel>) {
|
||||
this.items = items
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CreatorViewHolder {
|
||||
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_home_recent_debut_creator, parent, false)
|
||||
view.layoutParams = recyclerItemLayoutParams(parent)
|
||||
return CreatorViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: CreatorViewHolder, position: Int) {
|
||||
holder.bind(items[position])
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = items.size
|
||||
|
||||
class CreatorViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
private val profileImage = itemView.findViewById<ImageView>(R.id.iv_home_recent_debut_creator_profile)
|
||||
private val nicknameText = itemView.findViewById<TextView>(R.id.tv_home_recent_debut_creator_nickname)
|
||||
|
||||
fun bind(item: HomeRecommendationCreatorUiModel) {
|
||||
profileImage.loadUrl(item.profileImage)
|
||||
nicknameText.text = item.nickname
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class HomeFirstAudioAdapter : RecyclerView.Adapter<HomeFirstAudioAdapter.AudioViewHolder>() {
|
||||
private var items: List<HomeRecommendationFirstAudioContentUiModel> = emptyList()
|
||||
|
||||
fun submitItems(items: List<HomeRecommendationFirstAudioContentUiModel>) {
|
||||
this.items = items
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AudioViewHolder {
|
||||
val view = LayoutInflater.from(parent.context).inflate(
|
||||
R.layout.view_audio_content_card,
|
||||
parent,
|
||||
false
|
||||
) as AudioContentCardView
|
||||
view.layoutParams = recyclerItemLayoutParams(parent)
|
||||
return AudioViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: AudioViewHolder, position: Int) {
|
||||
holder.bind(items[position])
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = items.size
|
||||
|
||||
class AudioViewHolder(
|
||||
private val view: AudioContentCardView
|
||||
) : RecyclerView.ViewHolder(view) {
|
||||
fun bind(item: HomeRecommendationFirstAudioContentUiModel) {
|
||||
view.setSize(AudioContentCardSize.Medium)
|
||||
view.setContent(item.title, item.creatorNickname)
|
||||
view.thumbnailView().loadUrl(item.coverImage)
|
||||
view.setTags(item.tags)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class HomeAiCharacterAdapter : RecyclerView.Adapter<HomeAiCharacterAdapter.CharacterViewHolder>() {
|
||||
private var items: List<HomeRecommendationAiCharacterUiModel> = emptyList()
|
||||
|
||||
fun submitItems(items: List<HomeRecommendationAiCharacterUiModel>) {
|
||||
this.items = items
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CharacterViewHolder {
|
||||
val view = LayoutInflater.from(parent.context).inflate(
|
||||
R.layout.view_character_chat_thumbnail,
|
||||
parent,
|
||||
false
|
||||
) as CharacterChatThumbnailView
|
||||
view.layoutParams = recyclerItemLayoutParams(parent)
|
||||
return CharacterViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: CharacterViewHolder, position: Int) {
|
||||
holder.bind(items[position].item)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = items.size
|
||||
|
||||
class CharacterViewHolder(
|
||||
private val view: CharacterChatThumbnailView
|
||||
) : RecyclerView.ViewHolder(view) {
|
||||
fun bind(item: CharacterChatThumbnailItem) {
|
||||
view.bind(item)
|
||||
view.imageView().loadUrl(item.imageUrl)
|
||||
view.setOnCharacterClick(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class HomeGenreCreatorAdapter : HomeCreatorProfileAdapter()
|
||||
|
||||
class HomeCheerCreatorAdapter : HomeCreatorProfileAdapter()
|
||||
|
||||
open class HomeCreatorProfileAdapter : RecyclerView.Adapter<HomeCreatorProfileAdapter.CreatorViewHolder>() {
|
||||
private var items: List<HomeRecommendationCreatorUiModel> = emptyList()
|
||||
|
||||
fun submitItems(items: List<HomeRecommendationCreatorUiModel>) {
|
||||
this.items = items
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CreatorViewHolder {
|
||||
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_home_creator_profile, parent, false)
|
||||
view.layoutParams = recyclerItemLayoutParams(parent)
|
||||
return CreatorViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: CreatorViewHolder, position: Int) {
|
||||
holder.bind(items[position])
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = items.size
|
||||
|
||||
class CreatorViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
private val profileImage = itemView.findViewById<ImageView>(R.id.iv_home_creator_profile)
|
||||
private val nicknameText = itemView.findViewById<TextView>(R.id.tv_home_creator_profile_nickname)
|
||||
|
||||
fun bind(item: HomeRecommendationCreatorUiModel) {
|
||||
profileImage.loadUrl(item.profileImage)
|
||||
nicknameText.text = item.nickname
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object HomeFollowAllButtonBinder {
|
||||
fun bind(
|
||||
view: View,
|
||||
creatorIds: List<Long>,
|
||||
isFollowCompleted: Boolean,
|
||||
onClick: (List<Long>) -> Unit
|
||||
) {
|
||||
val icon = view.findViewById<ImageView>(R.id.iv_home_follow_all_icon)
|
||||
val text = view.findViewById<TextView>(R.id.tv_home_follow_all)
|
||||
icon.setImageResource(if (isFollowCompleted) R.drawable.ic_new_following else R.drawable.ic_new_follow)
|
||||
text.setText(
|
||||
if (isFollowCompleted) {
|
||||
R.string.home_recommendation_follow_all_done
|
||||
} else {
|
||||
R.string.home_recommendation_follow_all
|
||||
}
|
||||
)
|
||||
view.isEnabled = !isFollowCompleted
|
||||
view.setOnClickListener {
|
||||
if (creatorIds.isNotEmpty()) onClick(creatorIds)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun recyclerItemLayoutParams(parent: ViewGroup): RecyclerView.LayoutParams {
|
||||
return RecyclerView.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
).apply { marginEnd = parent.resources.getDimensionPixelSize(R.dimen.spacing_12) }
|
||||
}
|
||||
@@ -65,13 +65,10 @@
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="@dimen/spacing_24">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
<kr.co.vividnext.sodalive.v2.widget.banner.BannerView
|
||||
android:id="@+id/rv_home_banners"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="160dp"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="@dimen/spacing_20"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
@@ -193,6 +190,10 @@
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="@dimen/spacing_20"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
|
||||
|
||||
<include
|
||||
android:id="@+id/view_home_genre_follow_all"
|
||||
layout="@layout/view_home_follow_all_button" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
@@ -213,6 +214,10 @@
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="@dimen/spacing_20"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
|
||||
|
||||
<include
|
||||
android:id="@+id/view_home_cheer_follow_all"
|
||||
layout="@layout/view_home_follow_all_button" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
@@ -220,7 +225,8 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="@dimen/spacing_24">
|
||||
android:paddingTop="@dimen/spacing_24"
|
||||
android:visibility="gone">
|
||||
|
||||
<include
|
||||
android:id="@+id/view_home_popular_community_title"
|
||||
|
||||
Reference in New Issue
Block a user