콘텐츠 메인 탭 - 채널별 **

- RecyclerView와 GridLayout으로 변경
This commit is contained in:
klaus 2025-02-17 18:05:59 +09:00
parent 189e757100
commit 04569f1e7e
20 changed files with 368 additions and 1495 deletions

View File

@ -16,7 +16,6 @@ import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentCurationRespon
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentMainItem import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentMainItem
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRanking import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRanking
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRankingItem import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRankingItem
import kr.co.vividnext.sodalive.audio_content.main.v2.GetPopularContentByCreatorResponse
import kr.co.vividnext.sodalive.audio_content.main.v2.alarm.GetContentMainTabAlarmResponse import kr.co.vividnext.sodalive.audio_content.main.v2.alarm.GetContentMainTabAlarmResponse
import kr.co.vividnext.sodalive.audio_content.main.v2.asmr.GetContentMainTabAsmrResponse import kr.co.vividnext.sodalive.audio_content.main.v2.asmr.GetContentMainTabAsmrResponse
import kr.co.vividnext.sodalive.audio_content.main.v2.content.GetContentMainTabContentResponse import kr.co.vividnext.sodalive.audio_content.main.v2.content.GetContentMainTabContentResponse
@ -257,7 +256,7 @@ interface AudioContentApi {
fun getPopularContentByCreator( fun getPopularContentByCreator(
@Query("creatorId") creatorId: Long, @Query("creatorId") creatorId: Long,
@Header("Authorization") authHeader: String @Header("Authorization") authHeader: String
): Single<ApiResponse<GetPopularContentByCreatorResponse>> ): Single<ApiResponse<List<GetAudioContentRankingItem>>>
@GET("/v2/audio-content/main/series") @GET("/v2/audio-content/main/series")
fun getContentMainSeries( fun getContentMainSeries(
@ -313,7 +312,7 @@ interface AudioContentApi {
fun getContentMainContentPopularContentByCreator( fun getContentMainContentPopularContentByCreator(
@Query("creatorId") creatorId: Long, @Query("creatorId") creatorId: Long,
@Header("Authorization") authHeader: String @Header("Authorization") authHeader: String
): Single<ApiResponse<GetPopularContentByCreatorResponse>> ): Single<ApiResponse<List<GetAudioContentRankingItem>>>
@GET("/v2/audio-content/main/alarm") @GET("/v2/audio-content/main/alarm")
fun getContentMainAlarm( fun getContentMainAlarm(
@ -337,7 +336,7 @@ interface AudioContentApi {
fun getPopularAsmrContentByCreator( fun getPopularAsmrContentByCreator(
@Query("creatorId") creatorId: Long, @Query("creatorId") creatorId: Long,
@Header("Authorization") authHeader: String @Header("Authorization") authHeader: String
): Single<ApiResponse<GetPopularContentByCreatorResponse>> ): Single<ApiResponse<List<GetAudioContentRankingItem>>>
@GET("/v2/audio-content/main/replay") @GET("/v2/audio-content/main/replay")
fun getContentMainReplay( fun getContentMainReplay(
@ -348,7 +347,7 @@ interface AudioContentApi {
fun getPopularReplayContentByCreator( fun getPopularReplayContentByCreator(
@Query("creatorId") creatorId: Long, @Query("creatorId") creatorId: Long,
@Header("Authorization") authHeader: String @Header("Authorization") authHeader: String
): Single<ApiResponse<GetPopularContentByCreatorResponse>> ): Single<ApiResponse<List<GetAudioContentRankingItem>>>
@GET("/v2/audio-content/main/free") @GET("/v2/audio-content/main/free")
fun getContentMainFree( fun getContentMainFree(

View File

@ -1,13 +0,0 @@
package kr.co.vividnext.sodalive.audio_content.main.v2
import androidx.annotation.Keep
import com.google.gson.annotations.SerializedName
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRankingItem
@Keep
data class GetPopularContentByCreatorResponse(
@SerializedName("salesRankContentList")
val salesRankContentList: List<GetAudioContentRankingItem>,
@SerializedName("salesCountRankContentList")
val salesCountRankContentList: List<GetAudioContentRankingItem>
)

View File

@ -0,0 +1,95 @@
package kr.co.vividnext.sodalive.audio_content.main.v2
import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.MultiTransformation
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.bumptech.glide.load.resource.bitmap.CircleCrop
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.bumptech.glide.request.RequestOptions
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRankingItem
import kr.co.vividnext.sodalive.databinding.ItemAudioContentMainTabPopularContentBinding
import kr.co.vividnext.sodalive.extensions.dpToPx
class PopularContentByCreatorAdapter(
private val itemWidth: Int,
private val onClickItem: (Long) -> Unit,
private val onClickCreator: (Long) -> Unit
) : RecyclerView.Adapter<PopularContentByCreatorAdapter.ViewHolder>() {
private val items = mutableListOf<GetAudioContentRankingItem>()
inner class ViewHolder(
private val context: Context,
private val binding: ItemAudioContentMainTabPopularContentBinding
) : RecyclerView.ViewHolder(binding.root) {
fun bind(item: GetAudioContentRankingItem) {
val lp = binding.ivCover.layoutParams as LinearLayout.LayoutParams
lp.width = itemWidth
lp.height = itemWidth
binding.ivCover.layoutParams = lp
Glide
.with(context)
.load(item.coverImageUrl)
.apply(
RequestOptions().transform(
MultiTransformation(
CenterCrop(),
RoundedCorners(5.3f.dpToPx().toInt())
)
)
)
.placeholder(R.drawable.bg_black)
.into(binding.ivCover)
Glide
.with(context)
.load(item.creatorProfileImageUrl)
.apply(
RequestOptions().transform(
CircleCrop()
)
)
.placeholder(R.drawable.bg_black)
.into(binding.ivCreator)
binding.tvTitle.text = item.title
binding.tvNickname.text = item.creatorNickname
binding.ivCover.setOnClickListener { onClickItem(item.contentId) }
binding.ivCreator.setOnClickListener { onClickCreator(item.creatorId) }
binding.tvNickname.setOnClickListener { onClickCreator(item.creatorId) }
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
parent.context,
ItemAudioContentMainTabPopularContentBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
override fun getItemCount() = items.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(items[position])
}
@SuppressLint("NotifyDataSetChanged")
fun addItems(items: List<GetAudioContentRankingItem>) {
this.items.clear()
this.items.addAll(items)
notifyDataSetChanged()
}
}

View File

@ -6,9 +6,7 @@ import android.graphics.Rect
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.annotation.OptIn import androidx.annotation.OptIn
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
@ -16,9 +14,6 @@ import androidx.media3.common.util.UnstableApi
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import coil.load
import coil.transform.CircleCropTransformation
import coil.transform.RoundedCornersTransformation
import com.zhpan.bannerview.BaseBannerAdapter import com.zhpan.bannerview.BaseBannerAdapter
import com.zhpan.indicator.enums.IndicatorSlideMode import com.zhpan.indicator.enums.IndicatorSlideMode
import com.zhpan.indicator.enums.IndicatorStyle import com.zhpan.indicator.enums.IndicatorStyle
@ -26,14 +21,15 @@ import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
import kr.co.vividnext.sodalive.audio_content.main.AudioContentBannerType import kr.co.vividnext.sodalive.audio_content.main.AudioContentBannerType
import kr.co.vividnext.sodalive.audio_content.main.AudioContentMainContentAdapter import kr.co.vividnext.sodalive.audio_content.main.AudioContentMainContentAdapter
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRankingItem
import kr.co.vividnext.sodalive.audio_content.main.banner.AudioContentMainBannerAdapter import kr.co.vividnext.sodalive.audio_content.main.banner.AudioContentMainBannerAdapter
import kr.co.vividnext.sodalive.audio_content.main.ranking.AudioContentMainRankingAdapter import kr.co.vividnext.sodalive.audio_content.main.ranking.AudioContentMainRankingAdapter
import kr.co.vividnext.sodalive.audio_content.main.v2.AudioContentMainContentCurationAdapter import kr.co.vividnext.sodalive.audio_content.main.v2.AudioContentMainContentCurationAdapter
import kr.co.vividnext.sodalive.audio_content.main.v2.ContentRankCreatorAdapter import kr.co.vividnext.sodalive.audio_content.main.v2.ContentRankCreatorAdapter
import kr.co.vividnext.sodalive.audio_content.main.v2.PopularContentByCreatorAdapter
import kr.co.vividnext.sodalive.audio_content.series.detail.SeriesDetailActivity import kr.co.vividnext.sodalive.audio_content.series.detail.SeriesDetailActivity
import kr.co.vividnext.sodalive.base.BaseFragment import kr.co.vividnext.sodalive.base.BaseFragment
import kr.co.vividnext.sodalive.common.Constants import kr.co.vividnext.sodalive.common.Constants
import kr.co.vividnext.sodalive.common.GridSpacingItemDecoration
import kr.co.vividnext.sodalive.common.LoadingDialog import kr.co.vividnext.sodalive.common.LoadingDialog
import kr.co.vividnext.sodalive.databinding.FragmentAudioContentMainTabAsmrBinding import kr.co.vividnext.sodalive.databinding.FragmentAudioContentMainTabAsmrBinding
import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity
@ -56,6 +52,7 @@ class AudioContentMainTabAsmrFragment : BaseFragment<FragmentAudioContentMainTab
private lateinit var contentRankingAdapter: AudioContentMainRankingAdapter private lateinit var contentRankingAdapter: AudioContentMainRankingAdapter
private lateinit var curationAdapter: AudioContentMainContentCurationAdapter private lateinit var curationAdapter: AudioContentMainContentCurationAdapter
private lateinit var contentRankCreatorAdapter: ContentRankCreatorAdapter private lateinit var contentRankCreatorAdapter: ContentRankCreatorAdapter
private lateinit var popularContentByCreatorAdapter: PopularContentByCreatorAdapter
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
@ -71,6 +68,7 @@ class AudioContentMainTabAsmrFragment : BaseFragment<FragmentAudioContentMainTab
setupContentBanner() setupContentBanner()
setupNewContent() setupNewContent()
setupContentRanking() setupContentRanking()
setupPopularContentCreator()
setupPopularContentByCreator() setupPopularContentByCreator()
setupEventBanner() setupEventBanner()
setupCuration() setupCuration()
@ -389,9 +387,10 @@ class AudioContentMainTabAsmrFragment : BaseFragment<FragmentAudioContentMainTab
} }
} }
private fun setupPopularContentByCreator() { private fun setupPopularContentCreator() {
contentRankCreatorAdapter = ContentRankCreatorAdapter { contentRankCreatorAdapter = ContentRankCreatorAdapter {
loadingPopularContentByCreator() binding.llNoItems.visibility = View.VISIBLE
binding.rvRankingSalesCount.visibility = View.GONE
viewModel.getPopularContentByCreator(it) viewModel.getPopularContentByCreator(it)
} }
@ -441,12 +440,47 @@ class AudioContentMainTabAsmrFragment : BaseFragment<FragmentAudioContentMainTab
} }
} }
private fun loadingPopularContentByCreator() { private fun setupPopularContentByCreator() {
binding.llSales2.visibility = View.GONE popularContentByCreatorAdapter = PopularContentByCreatorAdapter(
binding.llSalesTop2.visibility = View.GONE itemWidth = ((screenWidth - 13.3f.dpToPx() * 3) / 2).toInt(),
binding.llSalesCount2.visibility = View.GONE onClickItem = { contentId ->
binding.llSalesCountTop2.visibility = View.GONE startActivity(
binding.llNoItems.visibility = View.VISIBLE Intent(requireActivity(), AudioContentDetailActivity::class.java).apply {
putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, contentId)
}
)
},
onClickCreator = { creatorId ->
startActivity(
Intent(requireActivity(), UserProfileActivity::class.java).apply {
putExtra(Constants.EXTRA_USER_ID, creatorId)
}
)
}
)
val recyclerView = binding.rvRankingSalesCount
recyclerView.layoutManager = GridLayoutManager(requireContext(), 2)
recyclerView.addItemDecoration(
GridSpacingItemDecoration(
2,
13.3f.dpToPx().toInt(),
false
)
)
recyclerView.adapter = popularContentByCreatorAdapter
viewModel.salesCountRankContentListLiveData.observe(viewLifecycleOwner) {
if (it.isNotEmpty()) {
binding.llNoItems.visibility = View.GONE
recyclerView.visibility = View.VISIBLE
popularContentByCreatorAdapter.addItems(it)
} else {
binding.llNoItems.visibility = View.VISIBLE
recyclerView.visibility = View.GONE
}
}
} }
private fun bindData() { private fun bindData() {
@ -461,94 +495,5 @@ class AudioContentMainTabAsmrFragment : BaseFragment<FragmentAudioContentMainTab
loadingDialog.dismiss() loadingDialog.dismiss()
} }
} }
viewModel.salesRankContentListLiveData.observe(viewLifecycleOwner) {
if (it.isNotEmpty()) {
binding.llNoItems.visibility = View.GONE
binding.llSalesTop2.visibility = View.VISIBLE
setSalesRankContent(
item = it[0],
titleTextView = binding.tvSalesTitle1,
coverImageView = binding.ivSales1,
creatorTextView = binding.tvSalesCreator1,
creatorImageView = binding.ivSalesCreator1
)
if (it.size > 1) {
binding.llSales2.visibility = View.VISIBLE
setSalesRankContent(
item = it[1],
titleTextView = binding.tvSalesTitle2,
coverImageView = binding.ivSales2,
creatorTextView = binding.tvSalesCreator2,
creatorImageView = binding.ivSalesCreator2
)
}
}
}
viewModel.salesCountRankContentListLiveData.observe(viewLifecycleOwner) {
if (it.isNotEmpty()) {
binding.llNoItems.visibility = View.GONE
binding.llSalesCountTop2.visibility = View.VISIBLE
setSalesRankContent(
item = it[0],
titleTextView = binding.tvSalesCountTitle1,
coverImageView = binding.ivSalesCount1,
creatorTextView = binding.tvSalesCountCreator1,
creatorImageView = binding.ivSalesCountCreator1
)
if (it.size > 1) {
binding.llSalesCount2.visibility = View.VISIBLE
setSalesRankContent(
item = it[1],
titleTextView = binding.tvSalesCountTitle2,
coverImageView = binding.ivSalesCount2,
creatorTextView = binding.tvSalesCountCreator2,
creatorImageView = binding.ivSalesCountCreator2
)
}
}
}
}
private fun setSalesRankContent(
item: GetAudioContentRankingItem,
titleTextView: TextView,
creatorTextView: TextView,
coverImageView: ImageView,
creatorImageView: ImageView
) {
coverImageView.load(item.coverImageUrl) {
crossfade(true)
placeholder(R.drawable.bg_placeholder)
transformations(RoundedCornersTransformation(5.3f.dpToPx()))
}
titleTextView.text = item.title
creatorTextView.text = item.creatorNickname
creatorImageView.load(item.creatorProfileImageUrl) {
transformations(CircleCropTransformation())
placeholder(R.drawable.ic_place_holder)
crossfade(true)
}
coverImageView.setOnClickListener {
startActivity(
Intent(requireActivity(), AudioContentDetailActivity::class.java).apply {
putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, item.contentId)
}
)
}
creatorImageView.setOnClickListener {
startActivity(
Intent(requireActivity(), UserProfileActivity::class.java).apply {
putExtra(Constants.EXTRA_USER_ID, item.creatorId)
}
)
}
} }
} }

View File

@ -41,10 +41,6 @@ class AudioContentMainTabAsmrViewModel(
val contentCreatorListLiveData: LiveData<List<ContentCreatorResponse>> val contentCreatorListLiveData: LiveData<List<ContentCreatorResponse>>
get() = _contentCreatorListLiveData get() = _contentCreatorListLiveData
private val _salesRankContentListLiveData = MutableLiveData<List<GetAudioContentRankingItem>>()
val salesRankContentListLiveData: LiveData<List<GetAudioContentRankingItem>>
get() = _salesRankContentListLiveData
private val _salesCountRankContentListLiveData = private val _salesCountRankContentListLiveData =
MutableLiveData<List<GetAudioContentRankingItem>>() MutableLiveData<List<GetAudioContentRankingItem>>()
val salesCountRankContentListLiveData: LiveData<List<GetAudioContentRankingItem>> val salesCountRankContentListLiveData: LiveData<List<GetAudioContentRankingItem>>
@ -73,7 +69,6 @@ class AudioContentMainTabAsmrViewModel(
_newContentListLiveData.value = data.newAsmrContentList _newContentListLiveData.value = data.newAsmrContentList
_contentRankingLiveData.value = data.rankAsmrContentList _contentRankingLiveData.value = data.rankAsmrContentList
_contentCreatorListLiveData.value = data.creatorList _contentCreatorListLiveData.value = data.creatorList
_salesRankContentListLiveData.value = data.salesRankContentList
_salesCountRankContentListLiveData.value = _salesCountRankContentListLiveData.value =
data.salesCountRankContentList data.salesCountRankContentList
_eventLiveData.value = data.eventBannerList.eventList _eventLiveData.value = data.eventBannerList.eventList
@ -112,10 +107,7 @@ class AudioContentMainTabAsmrViewModel(
{ {
_isLoading.value = false _isLoading.value = false
if (it.success && it.data != null) { if (it.success && it.data != null) {
val data = it.data _salesCountRankContentListLiveData.value = it.data!!
_salesRankContentListLiveData.value = data.salesRankContentList
_salesCountRankContentListLiveData.value =
data.salesCountRankContentList
} else { } else {
if (it.message != null) { if (it.message != null) {
_toastLiveData.postValue(it.message) _toastLiveData.postValue(it.message)

View File

@ -19,8 +19,6 @@ data class GetContentMainTabAsmrResponse(
val rankAsmrContentList: List<GetAudioContentRankingItem>, val rankAsmrContentList: List<GetAudioContentRankingItem>,
@SerializedName("creatorList") @SerializedName("creatorList")
val creatorList: List<ContentCreatorResponse>, val creatorList: List<ContentCreatorResponse>,
@SerializedName("salesRankContentList")
val salesRankContentList: List<GetAudioContentRankingItem>,
@SerializedName("salesCountRankContentList") @SerializedName("salesCountRankContentList")
val salesCountRankContentList: List<GetAudioContentRankingItem>, val salesCountRankContentList: List<GetAudioContentRankingItem>,
@SerializedName("eventBannerList") @SerializedName("eventBannerList")

View File

@ -6,9 +6,7 @@ import android.graphics.Rect
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.annotation.OptIn import androidx.annotation.OptIn
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
@ -16,9 +14,6 @@ import androidx.media3.common.util.UnstableApi
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import coil.load
import coil.transform.CircleCropTransformation
import coil.transform.RoundedCornersTransformation
import com.zhpan.bannerview.BaseBannerAdapter import com.zhpan.bannerview.BaseBannerAdapter
import com.zhpan.indicator.enums.IndicatorSlideMode import com.zhpan.indicator.enums.IndicatorSlideMode
import com.zhpan.indicator.enums.IndicatorStyle import com.zhpan.indicator.enums.IndicatorStyle
@ -27,14 +22,15 @@ import kr.co.vividnext.sodalive.audio_content.all.AudioContentNewAllActivity
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
import kr.co.vividnext.sodalive.audio_content.main.AudioContentBannerType import kr.co.vividnext.sodalive.audio_content.main.AudioContentBannerType
import kr.co.vividnext.sodalive.audio_content.main.AudioContentMainContentAdapter import kr.co.vividnext.sodalive.audio_content.main.AudioContentMainContentAdapter
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRankingItem
import kr.co.vividnext.sodalive.audio_content.main.banner.AudioContentMainBannerAdapter import kr.co.vividnext.sodalive.audio_content.main.banner.AudioContentMainBannerAdapter
import kr.co.vividnext.sodalive.audio_content.main.new_content.AudioContentMainNewContentThemeAdapter import kr.co.vividnext.sodalive.audio_content.main.new_content.AudioContentMainNewContentThemeAdapter
import kr.co.vividnext.sodalive.audio_content.main.ranking.AudioContentMainRankingAdapter import kr.co.vividnext.sodalive.audio_content.main.ranking.AudioContentMainRankingAdapter
import kr.co.vividnext.sodalive.audio_content.main.v2.ContentRankCreatorAdapter import kr.co.vividnext.sodalive.audio_content.main.v2.ContentRankCreatorAdapter
import kr.co.vividnext.sodalive.audio_content.main.v2.PopularContentByCreatorAdapter
import kr.co.vividnext.sodalive.audio_content.series.detail.SeriesDetailActivity import kr.co.vividnext.sodalive.audio_content.series.detail.SeriesDetailActivity
import kr.co.vividnext.sodalive.base.BaseFragment import kr.co.vividnext.sodalive.base.BaseFragment
import kr.co.vividnext.sodalive.common.Constants import kr.co.vividnext.sodalive.common.Constants
import kr.co.vividnext.sodalive.common.GridSpacingItemDecoration
import kr.co.vividnext.sodalive.common.LoadingDialog import kr.co.vividnext.sodalive.common.LoadingDialog
import kr.co.vividnext.sodalive.databinding.FragmentAudioContentMainTabContentBinding import kr.co.vividnext.sodalive.databinding.FragmentAudioContentMainTabContentBinding
import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity
@ -57,6 +53,7 @@ class AudioContentMainTabContentFragment : BaseFragment<FragmentAudioContentMain
private lateinit var contentRankingSortAdapter: AudioContentMainNewContentThemeAdapter private lateinit var contentRankingSortAdapter: AudioContentMainNewContentThemeAdapter
private lateinit var contentRankingAdapter: AudioContentMainRankingAdapter private lateinit var contentRankingAdapter: AudioContentMainRankingAdapter
private lateinit var contentRankCreatorAdapter: ContentRankCreatorAdapter private lateinit var contentRankCreatorAdapter: ContentRankCreatorAdapter
private lateinit var popularContentByCreatorAdapter: PopularContentByCreatorAdapter
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
@ -75,6 +72,7 @@ class AudioContentMainTabContentFragment : BaseFragment<FragmentAudioContentMain
setupContentRankingSortType() setupContentRankingSortType()
setupContentRanking() setupContentRanking()
setupEventBanner() setupEventBanner()
setupPopularContentCreator()
setupPopularContentByCreator() setupPopularContentByCreator()
} }
@ -409,9 +407,10 @@ class AudioContentMainTabContentFragment : BaseFragment<FragmentAudioContentMain
} }
} }
private fun setupPopularContentByCreator() { private fun setupPopularContentCreator() {
contentRankCreatorAdapter = ContentRankCreatorAdapter { contentRankCreatorAdapter = ContentRankCreatorAdapter {
loadingPopularContentByCreator() binding.llNoItems.visibility = View.VISIBLE
binding.rvRankingSalesCount.visibility = View.GONE
viewModel.getPopularContentByCreator(it) viewModel.getPopularContentByCreator(it)
} }
@ -461,12 +460,47 @@ class AudioContentMainTabContentFragment : BaseFragment<FragmentAudioContentMain
} }
} }
private fun loadingPopularContentByCreator() { private fun setupPopularContentByCreator() {
binding.llSales2.visibility = View.GONE popularContentByCreatorAdapter = PopularContentByCreatorAdapter(
binding.llSalesTop2.visibility = View.GONE itemWidth = ((screenWidth - 13.3f.dpToPx() * 3) / 2).toInt(),
binding.llSalesCount2.visibility = View.GONE onClickItem = { contentId ->
binding.llSalesCountTop2.visibility = View.GONE startActivity(
binding.llNoItems.visibility = View.VISIBLE Intent(requireActivity(), AudioContentDetailActivity::class.java).apply {
putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, contentId)
}
)
},
onClickCreator = { creatorId ->
startActivity(
Intent(requireActivity(), UserProfileActivity::class.java).apply {
putExtra(Constants.EXTRA_USER_ID, creatorId)
}
)
}
)
val recyclerView = binding.rvRankingSalesCount
recyclerView.layoutManager = GridLayoutManager(requireContext(), 2)
recyclerView.addItemDecoration(
GridSpacingItemDecoration(
2,
13.3f.dpToPx().toInt(),
false
)
)
recyclerView.adapter = popularContentByCreatorAdapter
viewModel.salesCountRankContentListLiveData.observe(viewLifecycleOwner) {
if (it.isNotEmpty()) {
binding.llNoItems.visibility = View.GONE
recyclerView.visibility = View.VISIBLE
popularContentByCreatorAdapter.addItems(it)
} else {
binding.llNoItems.visibility = View.VISIBLE
recyclerView.visibility = View.GONE
}
}
} }
private fun bindData() { private fun bindData() {
@ -481,94 +515,5 @@ class AudioContentMainTabContentFragment : BaseFragment<FragmentAudioContentMain
loadingDialog.dismiss() loadingDialog.dismiss()
} }
} }
viewModel.salesRankContentListLiveData.observe(viewLifecycleOwner) {
if (it.isNotEmpty()) {
binding.llNoItems.visibility = View.GONE
binding.llSalesTop2.visibility = View.VISIBLE
setSalesRankContent(
item = it[0],
titleTextView = binding.tvSalesTitle1,
coverImageView = binding.ivSales1,
creatorTextView = binding.tvSalesCreator1,
creatorImageView = binding.ivSalesCreator1
)
if (it.size > 1) {
binding.llSales2.visibility = View.VISIBLE
setSalesRankContent(
item = it[1],
titleTextView = binding.tvSalesTitle2,
coverImageView = binding.ivSales2,
creatorTextView = binding.tvSalesCreator2,
creatorImageView = binding.ivSalesCreator2
)
}
}
}
viewModel.salesCountRankContentListLiveData.observe(viewLifecycleOwner) {
if (it.isNotEmpty()) {
binding.llNoItems.visibility = View.GONE
binding.llSalesCountTop2.visibility = View.VISIBLE
setSalesRankContent(
item = it[0],
titleTextView = binding.tvSalesCountTitle1,
coverImageView = binding.ivSalesCount1,
creatorTextView = binding.tvSalesCountCreator1,
creatorImageView = binding.ivSalesCountCreator1
)
if (it.size > 1) {
binding.llSalesCount2.visibility = View.VISIBLE
setSalesRankContent(
item = it[1],
titleTextView = binding.tvSalesCountTitle2,
coverImageView = binding.ivSalesCount2,
creatorTextView = binding.tvSalesCountCreator2,
creatorImageView = binding.ivSalesCountCreator2
)
}
}
}
}
private fun setSalesRankContent(
item: GetAudioContentRankingItem,
titleTextView: TextView,
creatorTextView: TextView,
coverImageView: ImageView,
creatorImageView: ImageView
) {
coverImageView.load(item.coverImageUrl) {
crossfade(true)
placeholder(R.drawable.bg_placeholder)
transformations(RoundedCornersTransformation(5.3f.dpToPx()))
}
titleTextView.text = item.title
creatorTextView.text = item.creatorNickname
creatorImageView.load(item.creatorProfileImageUrl) {
transformations(CircleCropTransformation())
placeholder(R.drawable.ic_place_holder)
crossfade(true)
}
coverImageView.setOnClickListener {
startActivity(
Intent(requireActivity(), AudioContentDetailActivity::class.java).apply {
putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, item.contentId)
}
)
}
creatorImageView.setOnClickListener {
startActivity(
Intent(requireActivity(), UserProfileActivity::class.java).apply {
putExtra(Constants.EXTRA_USER_ID, item.creatorId)
}
)
}
} }
} }

View File

@ -52,10 +52,6 @@ class AudioContentMainTabContentViewModel(
val contentRankCreatorListLiveData: LiveData<List<ContentCreatorResponse>> val contentRankCreatorListLiveData: LiveData<List<ContentCreatorResponse>>
get() = _contentRankCreatorListLiveData get() = _contentRankCreatorListLiveData
private val _salesRankContentListLiveData = MutableLiveData<List<GetAudioContentRankingItem>>()
val salesRankContentListLiveData: LiveData<List<GetAudioContentRankingItem>>
get() = _salesRankContentListLiveData
private val _salesCountRankContentListLiveData = private val _salesCountRankContentListLiveData =
MutableLiveData<List<GetAudioContentRankingItem>>() MutableLiveData<List<GetAudioContentRankingItem>>()
val salesCountRankContentListLiveData: LiveData<List<GetAudioContentRankingItem>> val salesCountRankContentListLiveData: LiveData<List<GetAudioContentRankingItem>>
@ -83,7 +79,6 @@ class AudioContentMainTabContentViewModel(
_eventLiveData.value = data.eventBannerList.eventList _eventLiveData.value = data.eventBannerList.eventList
_contentRankCreatorListLiveData.value = data.contentRankCreatorList _contentRankCreatorListLiveData.value = data.contentRankCreatorList
_salesRankContentListLiveData.value = data.salesRankContentList
_salesCountRankContentListLiveData.value = _salesCountRankContentListLiveData.value =
data.salesCountRankContentList data.salesCountRankContentList
} else { } else {
@ -191,10 +186,7 @@ class AudioContentMainTabContentViewModel(
{ {
_isLoading.value = false _isLoading.value = false
if (it.success && it.data != null) { if (it.success && it.data != null) {
val data = it.data _salesCountRankContentListLiveData.value = it.data!!
_salesRankContentListLiveData.value = data.salesRankContentList
_salesCountRankContentListLiveData.value =
data.salesCountRankContentList
} else { } else {
if (it.message != null) { if (it.message != null) {
_toastLiveData.postValue(it.message) _toastLiveData.postValue(it.message)

View File

@ -16,7 +16,6 @@ data class GetContentMainTabContentResponse(
@SerializedName("rankSortTypeList") val rankSortTypeList: List<String>, @SerializedName("rankSortTypeList") val rankSortTypeList: List<String>,
@SerializedName("rankContentList") val rankContentList: List<GetAudioContentRankingItem>, @SerializedName("rankContentList") val rankContentList: List<GetAudioContentRankingItem>,
@SerializedName("contentRankCreatorList") val contentRankCreatorList: List<ContentCreatorResponse>, @SerializedName("contentRankCreatorList") val contentRankCreatorList: List<ContentCreatorResponse>,
@SerializedName("salesRankContentList") val salesRankContentList: List<GetAudioContentRankingItem>,
@SerializedName("salesCountRankContentList") val salesCountRankContentList: List<GetAudioContentRankingItem>, @SerializedName("salesCountRankContentList") val salesCountRankContentList: List<GetAudioContentRankingItem>,
@SerializedName("eventBannerList") val eventBannerList: GetEventResponse @SerializedName("eventBannerList") val eventBannerList: GetEventResponse
) )

View File

@ -9,18 +9,13 @@ import android.text.SpannableString
import android.text.Spanned import android.text.Spanned
import android.text.style.ForegroundColorSpan import android.text.style.ForegroundColorSpan
import android.view.View import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.media3.common.util.UnstableApi import androidx.media3.common.util.UnstableApi
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import coil.load
import coil.transform.CircleCropTransformation
import coil.transform.RoundedCornersTransformation
import com.zhpan.bannerview.BaseBannerAdapter import com.zhpan.bannerview.BaseBannerAdapter
import com.zhpan.indicator.enums.IndicatorSlideMode import com.zhpan.indicator.enums.IndicatorSlideMode
import com.zhpan.indicator.enums.IndicatorStyle import com.zhpan.indicator.enums.IndicatorStyle
@ -29,17 +24,18 @@ import kr.co.vividnext.sodalive.audio_content.all.AudioContentRankingAllActivity
import kr.co.vividnext.sodalive.audio_content.box.AudioContentBoxActivity import kr.co.vividnext.sodalive.audio_content.box.AudioContentBoxActivity
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
import kr.co.vividnext.sodalive.audio_content.main.AudioContentBannerType import kr.co.vividnext.sodalive.audio_content.main.AudioContentBannerType
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRankingItem
import kr.co.vividnext.sodalive.audio_content.main.banner.AudioContentMainBannerAdapter import kr.co.vividnext.sodalive.audio_content.main.banner.AudioContentMainBannerAdapter
import kr.co.vividnext.sodalive.audio_content.main.new_content.AudioContentMainNewContentThemeAdapter import kr.co.vividnext.sodalive.audio_content.main.new_content.AudioContentMainNewContentThemeAdapter
import kr.co.vividnext.sodalive.audio_content.main.ranking.AudioContentMainRankingAdapter import kr.co.vividnext.sodalive.audio_content.main.ranking.AudioContentMainRankingAdapter
import kr.co.vividnext.sodalive.audio_content.main.v2.AudioContentMainActivity import kr.co.vividnext.sodalive.audio_content.main.v2.AudioContentMainActivity
import kr.co.vividnext.sodalive.audio_content.main.v2.AudioContentMainTab import kr.co.vividnext.sodalive.audio_content.main.v2.AudioContentMainTab
import kr.co.vividnext.sodalive.audio_content.main.v2.ContentRankCreatorAdapter import kr.co.vividnext.sodalive.audio_content.main.v2.ContentRankCreatorAdapter
import kr.co.vividnext.sodalive.audio_content.main.v2.PopularContentByCreatorAdapter
import kr.co.vividnext.sodalive.audio_content.series.detail.SeriesDetailActivity import kr.co.vividnext.sodalive.audio_content.series.detail.SeriesDetailActivity
import kr.co.vividnext.sodalive.audio_content.upload.AudioContentUploadActivity import kr.co.vividnext.sodalive.audio_content.upload.AudioContentUploadActivity
import kr.co.vividnext.sodalive.base.BaseFragment import kr.co.vividnext.sodalive.base.BaseFragment
import kr.co.vividnext.sodalive.common.Constants import kr.co.vividnext.sodalive.common.Constants
import kr.co.vividnext.sodalive.common.GridSpacingItemDecoration
import kr.co.vividnext.sodalive.common.LoadingDialog import kr.co.vividnext.sodalive.common.LoadingDialog
import kr.co.vividnext.sodalive.common.SharedPreferenceManager import kr.co.vividnext.sodalive.common.SharedPreferenceManager
import kr.co.vividnext.sodalive.databinding.FragmentAudioContentMainTabHomeBinding import kr.co.vividnext.sodalive.databinding.FragmentAudioContentMainTabHomeBinding
@ -69,6 +65,7 @@ class AudioContentMainTabHomeFragment : BaseFragment<FragmentAudioContentMainTab
private lateinit var rankContentAdapter: AudioContentMainRankingAdapter private lateinit var rankContentAdapter: AudioContentMainRankingAdapter
private lateinit var rankContentSortAdapter: AudioContentMainNewContentThemeAdapter private lateinit var rankContentSortAdapter: AudioContentMainNewContentThemeAdapter
private lateinit var contentRankCreatorAdapter: ContentRankCreatorAdapter private lateinit var contentRankCreatorAdapter: ContentRankCreatorAdapter
private lateinit var popularContentByCreatorAdapter: PopularContentByCreatorAdapter
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
@ -90,95 +87,6 @@ class AudioContentMainTabHomeFragment : BaseFragment<FragmentAudioContentMainTab
loadingDialog.dismiss() loadingDialog.dismiss()
} }
} }
viewModel.salesRankContentListLiveData.observe(viewLifecycleOwner) {
if (it.isNotEmpty()) {
binding.llNoItems.visibility = View.GONE
binding.llSalesTop2.visibility = View.VISIBLE
setSalesRankContent(
item = it[0],
titleTextView = binding.tvSalesTitle1,
coverImageView = binding.ivSales1,
creatorTextView = binding.tvSalesCreator1,
creatorImageView = binding.ivSalesCreator1
)
if (it.size > 1) {
binding.llSales2.visibility = View.VISIBLE
setSalesRankContent(
item = it[1],
titleTextView = binding.tvSalesTitle2,
coverImageView = binding.ivSales2,
creatorTextView = binding.tvSalesCreator2,
creatorImageView = binding.ivSalesCreator2
)
}
}
}
viewModel.salesCountRankContentListLiveData.observe(viewLifecycleOwner) {
if (it.isNotEmpty()) {
binding.llNoItems.visibility = View.GONE
binding.llSalesCountTop2.visibility = View.VISIBLE
setSalesRankContent(
item = it[0],
titleTextView = binding.tvSalesCountTitle1,
coverImageView = binding.ivSalesCount1,
creatorTextView = binding.tvSalesCountCreator1,
creatorImageView = binding.ivSalesCountCreator1
)
if (it.size > 1) {
binding.llSalesCount2.visibility = View.VISIBLE
setSalesRankContent(
item = it[1],
titleTextView = binding.tvSalesCountTitle2,
coverImageView = binding.ivSalesCount2,
creatorTextView = binding.tvSalesCountCreator2,
creatorImageView = binding.ivSalesCountCreator2
)
}
}
}
}
private fun setSalesRankContent(
item: GetAudioContentRankingItem,
titleTextView: TextView,
creatorTextView: TextView,
coverImageView: ImageView,
creatorImageView: ImageView
) {
coverImageView.load(item.coverImageUrl) {
crossfade(true)
placeholder(R.drawable.bg_placeholder)
transformations(RoundedCornersTransformation(5.3f.dpToPx()))
}
titleTextView.text = item.title
creatorTextView.text = item.creatorNickname
creatorImageView.load(item.creatorProfileImageUrl) {
transformations(CircleCropTransformation())
placeholder(R.drawable.ic_place_holder)
crossfade(true)
}
coverImageView.setOnClickListener {
startActivity(
Intent(requireActivity(), AudioContentDetailActivity::class.java).apply {
putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, item.contentId)
}
)
}
creatorImageView.setOnClickListener {
startActivity(
Intent(requireActivity(), UserProfileActivity::class.java).apply {
putExtra(Constants.EXTRA_USER_ID, item.creatorId)
}
)
}
} }
private fun setupView() { private fun setupView() {
@ -228,6 +136,7 @@ class AudioContentMainTabHomeFragment : BaseFragment<FragmentAudioContentMainTab
setupRankContentSortType() setupRankContentSortType()
setupRankContent() setupRankContent()
setupEventBanner() setupEventBanner()
setupPopularContentCreator()
setupPopularContentByCreator() setupPopularContentByCreator()
} }
@ -664,9 +573,10 @@ class AudioContentMainTabHomeFragment : BaseFragment<FragmentAudioContentMainTab
} }
} }
private fun setupPopularContentByCreator() { private fun setupPopularContentCreator() {
contentRankCreatorAdapter = ContentRankCreatorAdapter { contentRankCreatorAdapter = ContentRankCreatorAdapter {
loadingPopularContentByCreator() binding.llNoItems.visibility = View.VISIBLE
binding.rvRankingSalesCount.visibility = View.GONE
viewModel.getPopularContentByCreator(it) viewModel.getPopularContentByCreator(it)
} }
@ -716,11 +626,46 @@ class AudioContentMainTabHomeFragment : BaseFragment<FragmentAudioContentMainTab
} }
} }
private fun loadingPopularContentByCreator() { private fun setupPopularContentByCreator() {
binding.llSales2.visibility = View.GONE popularContentByCreatorAdapter = PopularContentByCreatorAdapter(
binding.llSalesTop2.visibility = View.GONE itemWidth = ((screenWidth - 13.3f.dpToPx() * 3) / 2).toInt(),
binding.llSalesCount2.visibility = View.GONE onClickItem = { contentId ->
binding.llSalesCountTop2.visibility = View.GONE startActivity(
binding.llNoItems.visibility = View.VISIBLE Intent(requireActivity(), AudioContentDetailActivity::class.java).apply {
putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, contentId)
}
)
},
onClickCreator = { creatorId ->
startActivity(
Intent(requireActivity(), UserProfileActivity::class.java).apply {
putExtra(Constants.EXTRA_USER_ID, creatorId)
}
)
}
)
val recyclerView = binding.rvRankingSalesCount
recyclerView.layoutManager = GridLayoutManager(requireContext(), 2)
recyclerView.addItemDecoration(
GridSpacingItemDecoration(
2,
13.3f.dpToPx().toInt(),
false
)
)
recyclerView.adapter = popularContentByCreatorAdapter
viewModel.salesCountRankContentListLiveData.observe(viewLifecycleOwner) {
if (it.isNotEmpty()) {
binding.llNoItems.visibility = View.GONE
recyclerView.visibility = View.VISIBLE
popularContentByCreatorAdapter.addItems(it)
} else {
binding.llNoItems.visibility = View.VISIBLE
recyclerView.visibility = View.GONE
}
}
} }
} }

View File

@ -60,10 +60,6 @@ class AudioContentMainTabHomeViewModel(
val contentRankCreatorListLiveData: LiveData<List<ContentCreatorResponse>> val contentRankCreatorListLiveData: LiveData<List<ContentCreatorResponse>>
get() = _contentRankCreatorListLiveData get() = _contentRankCreatorListLiveData
private val _salesRankContentListLiveData = MutableLiveData<List<GetAudioContentRankingItem>>()
val salesRankContentListLiveData: LiveData<List<GetAudioContentRankingItem>>
get() = _salesRankContentListLiveData
private val _salesCountRankContentListLiveData = private val _salesCountRankContentListLiveData =
MutableLiveData<List<GetAudioContentRankingItem>>() MutableLiveData<List<GetAudioContentRankingItem>>()
val salesCountRankContentListLiveData: LiveData<List<GetAudioContentRankingItem>> val salesCountRankContentListLiveData: LiveData<List<GetAudioContentRankingItem>>
@ -90,7 +86,6 @@ class AudioContentMainTabHomeViewModel(
_rankContentSortListLiveData.value = data.rankSortTypeList _rankContentSortListLiveData.value = data.rankSortTypeList
_eventLiveData.value = data.eventBannerList.eventList _eventLiveData.value = data.eventBannerList.eventList
_contentRankCreatorListLiveData.value = data.contentRankCreatorList _contentRankCreatorListLiveData.value = data.contentRankCreatorList
_salesRankContentListLiveData.value = data.salesRankContentList
_salesCountRankContentListLiveData.value = _salesCountRankContentListLiveData.value =
data.salesCountRankContentList data.salesCountRankContentList
} else { } else {
@ -162,10 +157,7 @@ class AudioContentMainTabHomeViewModel(
{ {
_isLoading.value = false _isLoading.value = false
if (it.success && it.data != null) { if (it.success && it.data != null) {
val data = it.data _salesCountRankContentListLiveData.value = it.data!!
_salesRankContentListLiveData.value = data.salesRankContentList
_salesCountRankContentListLiveData.value =
data.salesCountRankContentList
} else { } else {
if (it.message != null) { if (it.message != null) {
_toastLiveData.postValue(it.message) _toastLiveData.postValue(it.message)

View File

@ -19,6 +19,5 @@ data class GetContentMainTabHomeResponse(
val rankContentList: List<GetAudioContentRankingItem>, val rankContentList: List<GetAudioContentRankingItem>,
val eventBannerList: GetEventResponse, val eventBannerList: GetEventResponse,
val contentRankCreatorList: List<ContentCreatorResponse>, val contentRankCreatorList: List<ContentCreatorResponse>,
val salesRankContentList: List<GetAudioContentRankingItem>,
val salesCountRankContentList: List<GetAudioContentRankingItem> val salesCountRankContentList: List<GetAudioContentRankingItem>
) )

View File

@ -6,9 +6,7 @@ import android.graphics.Rect
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.annotation.OptIn import androidx.annotation.OptIn
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
@ -16,9 +14,6 @@ import androidx.media3.common.util.UnstableApi
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import coil.load
import coil.transform.CircleCropTransformation
import coil.transform.RoundedCornersTransformation
import com.zhpan.bannerview.BaseBannerAdapter import com.zhpan.bannerview.BaseBannerAdapter
import com.zhpan.indicator.enums.IndicatorSlideMode import com.zhpan.indicator.enums.IndicatorSlideMode
import com.zhpan.indicator.enums.IndicatorStyle import com.zhpan.indicator.enums.IndicatorStyle
@ -26,14 +21,15 @@ import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
import kr.co.vividnext.sodalive.audio_content.main.AudioContentBannerType import kr.co.vividnext.sodalive.audio_content.main.AudioContentBannerType
import kr.co.vividnext.sodalive.audio_content.main.AudioContentMainContentAdapter import kr.co.vividnext.sodalive.audio_content.main.AudioContentMainContentAdapter
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRankingItem
import kr.co.vividnext.sodalive.audio_content.main.banner.AudioContentMainBannerAdapter import kr.co.vividnext.sodalive.audio_content.main.banner.AudioContentMainBannerAdapter
import kr.co.vividnext.sodalive.audio_content.main.ranking.AudioContentMainRankingAdapter import kr.co.vividnext.sodalive.audio_content.main.ranking.AudioContentMainRankingAdapter
import kr.co.vividnext.sodalive.audio_content.main.v2.AudioContentMainContentCurationAdapter import kr.co.vividnext.sodalive.audio_content.main.v2.AudioContentMainContentCurationAdapter
import kr.co.vividnext.sodalive.audio_content.main.v2.ContentRankCreatorAdapter import kr.co.vividnext.sodalive.audio_content.main.v2.ContentRankCreatorAdapter
import kr.co.vividnext.sodalive.audio_content.main.v2.PopularContentByCreatorAdapter
import kr.co.vividnext.sodalive.audio_content.series.detail.SeriesDetailActivity import kr.co.vividnext.sodalive.audio_content.series.detail.SeriesDetailActivity
import kr.co.vividnext.sodalive.base.BaseFragment import kr.co.vividnext.sodalive.base.BaseFragment
import kr.co.vividnext.sodalive.common.Constants import kr.co.vividnext.sodalive.common.Constants
import kr.co.vividnext.sodalive.common.GridSpacingItemDecoration
import kr.co.vividnext.sodalive.common.LoadingDialog import kr.co.vividnext.sodalive.common.LoadingDialog
import kr.co.vividnext.sodalive.databinding.FragmentAudioContentMainTabReplayBinding import kr.co.vividnext.sodalive.databinding.FragmentAudioContentMainTabReplayBinding
import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity
@ -55,6 +51,7 @@ class AudioContentMainTabReplayFragment : BaseFragment<FragmentAudioContentMainT
private lateinit var contentRankingAdapter: AudioContentMainRankingAdapter private lateinit var contentRankingAdapter: AudioContentMainRankingAdapter
private lateinit var curationAdapter: AudioContentMainContentCurationAdapter private lateinit var curationAdapter: AudioContentMainContentCurationAdapter
private lateinit var contentRankCreatorAdapter: ContentRankCreatorAdapter private lateinit var contentRankCreatorAdapter: ContentRankCreatorAdapter
private lateinit var popularContentByCreatorAdapter: PopularContentByCreatorAdapter
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
@ -70,6 +67,7 @@ class AudioContentMainTabReplayFragment : BaseFragment<FragmentAudioContentMainT
setupContentBanner() setupContentBanner()
setupNewContent() setupNewContent()
setupContentRanking() setupContentRanking()
setupPopularContentCreator()
setupPopularContentByCreator() setupPopularContentByCreator()
setupEventBanner() setupEventBanner()
setupCuration() setupCuration()
@ -274,9 +272,10 @@ class AudioContentMainTabReplayFragment : BaseFragment<FragmentAudioContentMainT
} }
} }
private fun setupPopularContentByCreator() { private fun setupPopularContentCreator() {
contentRankCreatorAdapter = ContentRankCreatorAdapter { contentRankCreatorAdapter = ContentRankCreatorAdapter {
loadingPopularContentByCreator() binding.llNoItems.visibility = View.VISIBLE
binding.rvRankingSalesCount.visibility = View.GONE
viewModel.getPopularContentByCreator(it) viewModel.getPopularContentByCreator(it)
} }
@ -326,12 +325,47 @@ class AudioContentMainTabReplayFragment : BaseFragment<FragmentAudioContentMainT
} }
} }
private fun loadingPopularContentByCreator() { private fun setupPopularContentByCreator() {
binding.llSales2.visibility = View.GONE popularContentByCreatorAdapter = PopularContentByCreatorAdapter(
binding.llSalesTop2.visibility = View.GONE itemWidth = ((screenWidth - 13.3f.dpToPx() * 3) / 2).toInt(),
binding.llSalesCount2.visibility = View.GONE onClickItem = { contentId ->
binding.llSalesCountTop2.visibility = View.GONE startActivity(
binding.llNoItems.visibility = View.VISIBLE Intent(requireActivity(), AudioContentDetailActivity::class.java).apply {
putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, contentId)
}
)
},
onClickCreator = { creatorId ->
startActivity(
Intent(requireActivity(), UserProfileActivity::class.java).apply {
putExtra(Constants.EXTRA_USER_ID, creatorId)
}
)
}
)
val recyclerView = binding.rvRankingSalesCount
recyclerView.layoutManager = GridLayoutManager(requireContext(), 2)
recyclerView.addItemDecoration(
GridSpacingItemDecoration(
2,
13.3f.dpToPx().toInt(),
false
)
)
recyclerView.adapter = popularContentByCreatorAdapter
viewModel.salesCountRankContentListLiveData.observe(viewLifecycleOwner) {
if (it.isNotEmpty()) {
binding.llNoItems.visibility = View.GONE
recyclerView.visibility = View.VISIBLE
popularContentByCreatorAdapter.addItems(it)
} else {
binding.llNoItems.visibility = View.VISIBLE
recyclerView.visibility = View.GONE
}
}
} }
private fun setupEventBanner() { private fun setupEventBanner() {
@ -460,94 +494,5 @@ class AudioContentMainTabReplayFragment : BaseFragment<FragmentAudioContentMainT
loadingDialog.dismiss() loadingDialog.dismiss()
} }
} }
viewModel.salesRankContentListLiveData.observe(viewLifecycleOwner) {
if (it.isNotEmpty()) {
binding.llNoItems.visibility = View.GONE
binding.llSalesTop2.visibility = View.VISIBLE
setSalesRankContent(
item = it[0],
titleTextView = binding.tvSalesTitle1,
coverImageView = binding.ivSales1,
creatorTextView = binding.tvSalesCreator1,
creatorImageView = binding.ivSalesCreator1
)
if (it.size > 1) {
binding.llSales2.visibility = View.VISIBLE
setSalesRankContent(
item = it[1],
titleTextView = binding.tvSalesTitle2,
coverImageView = binding.ivSales2,
creatorTextView = binding.tvSalesCreator2,
creatorImageView = binding.ivSalesCreator2
)
}
}
}
viewModel.salesCountRankContentListLiveData.observe(viewLifecycleOwner) {
if (it.isNotEmpty()) {
binding.llNoItems.visibility = View.GONE
binding.llSalesCountTop2.visibility = View.VISIBLE
setSalesRankContent(
item = it[0],
titleTextView = binding.tvSalesCountTitle1,
coverImageView = binding.ivSalesCount1,
creatorTextView = binding.tvSalesCountCreator1,
creatorImageView = binding.ivSalesCountCreator1
)
if (it.size > 1) {
binding.llSalesCount2.visibility = View.VISIBLE
setSalesRankContent(
item = it[1],
titleTextView = binding.tvSalesCountTitle2,
coverImageView = binding.ivSalesCount2,
creatorTextView = binding.tvSalesCountCreator2,
creatorImageView = binding.ivSalesCountCreator2
)
}
}
}
}
private fun setSalesRankContent(
item: GetAudioContentRankingItem,
titleTextView: TextView,
creatorTextView: TextView,
coverImageView: ImageView,
creatorImageView: ImageView
) {
coverImageView.load(item.coverImageUrl) {
crossfade(true)
placeholder(R.drawable.bg_placeholder)
transformations(RoundedCornersTransformation(5.3f.dpToPx()))
}
titleTextView.text = item.title
creatorTextView.text = item.creatorNickname
creatorImageView.load(item.creatorProfileImageUrl) {
transformations(CircleCropTransformation())
placeholder(R.drawable.ic_place_holder)
crossfade(true)
}
coverImageView.setOnClickListener {
startActivity(
Intent(requireActivity(), AudioContentDetailActivity::class.java).apply {
putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, item.contentId)
}
)
}
creatorImageView.setOnClickListener {
startActivity(
Intent(requireActivity(), UserProfileActivity::class.java).apply {
putExtra(Constants.EXTRA_USER_ID, item.creatorId)
}
)
}
} }
} }

View File

@ -16,7 +16,7 @@ import kr.co.vividnext.sodalive.settings.event.EventItem
class AudioContentMainTabReplayViewModel( class AudioContentMainTabReplayViewModel(
private val repository: AudioContentMainTabReplayRepository private val repository: AudioContentMainTabReplayRepository
): BaseViewModel() { ) : BaseViewModel() {
private val _toastLiveData = MutableLiveData<String?>() private val _toastLiveData = MutableLiveData<String?>()
val toastLiveData: LiveData<String?> val toastLiveData: LiveData<String?>
get() = _toastLiveData get() = _toastLiveData
@ -41,10 +41,6 @@ class AudioContentMainTabReplayViewModel(
val contentCreatorListLiveData: LiveData<List<ContentCreatorResponse>> val contentCreatorListLiveData: LiveData<List<ContentCreatorResponse>>
get() = _contentCreatorListLiveData get() = _contentCreatorListLiveData
private val _salesRankContentListLiveData = MutableLiveData<List<GetAudioContentRankingItem>>()
val salesRankContentListLiveData: LiveData<List<GetAudioContentRankingItem>>
get() = _salesRankContentListLiveData
private val _salesCountRankContentListLiveData = private val _salesCountRankContentListLiveData =
MutableLiveData<List<GetAudioContentRankingItem>>() MutableLiveData<List<GetAudioContentRankingItem>>()
val salesCountRankContentListLiveData: LiveData<List<GetAudioContentRankingItem>> val salesCountRankContentListLiveData: LiveData<List<GetAudioContentRankingItem>>
@ -73,7 +69,6 @@ class AudioContentMainTabReplayViewModel(
_newContentListLiveData.value = data.newLiveReplayContentList _newContentListLiveData.value = data.newLiveReplayContentList
_contentRankingLiveData.value = data.rankLiveReplayContentList _contentRankingLiveData.value = data.rankLiveReplayContentList
_contentCreatorListLiveData.value = data.creatorList _contentCreatorListLiveData.value = data.creatorList
_salesRankContentListLiveData.value = data.salesRankContentList
_salesCountRankContentListLiveData.value = _salesCountRankContentListLiveData.value =
data.salesCountRankContentList data.salesCountRankContentList
_eventLiveData.value = data.eventBannerList.eventList _eventLiveData.value = data.eventBannerList.eventList
@ -112,10 +107,7 @@ class AudioContentMainTabReplayViewModel(
{ {
_isLoading.value = false _isLoading.value = false
if (it.success && it.data != null) { if (it.success && it.data != null) {
val data = it.data _salesCountRankContentListLiveData.value = it.data!!
_salesRankContentListLiveData.value = data.salesRankContentList
_salesCountRankContentListLiveData.value =
data.salesCountRankContentList
} else { } else {
if (it.message != null) { if (it.message != null) {
_toastLiveData.postValue(it.message) _toastLiveData.postValue(it.message)

View File

@ -19,8 +19,6 @@ data class GetContentMainTabLiveReplayResponse(
val rankLiveReplayContentList: List<GetAudioContentRankingItem>, val rankLiveReplayContentList: List<GetAudioContentRankingItem>,
@SerializedName("creatorList") @SerializedName("creatorList")
val creatorList: List<ContentCreatorResponse>, val creatorList: List<ContentCreatorResponse>,
@SerializedName("salesRankContentList")
val salesRankContentList: List<GetAudioContentRankingItem>,
@SerializedName("salesCountRankContentList") @SerializedName("salesCountRankContentList")
val salesCountRankContentList: List<GetAudioContentRankingItem>, val salesCountRankContentList: List<GetAudioContentRankingItem>,
@SerializedName("eventBannerList") @SerializedName("eventBannerList")

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" <androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
@ -115,264 +114,13 @@
android:clipToPadding="false" android:clipToPadding="false"
android:paddingHorizontal="13.3dp" /> android:paddingHorizontal="13.3dp" />
<LinearLayout <androidx.recyclerview.widget.RecyclerView
android:id="@+id/ll_sales_top2" android:id="@+id/rv_ranking_sales_count"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="20dp" android:layout_marginTop="20dp"
android:baselineAligned="false" android:clipToPadding="false"
android:orientation="horizontal" android:paddingHorizontal="13.3dp" />
android:paddingHorizontal="13.3dp"
android:visibility="gone">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<ImageView
android:id="@+id/iv_sales_1"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_sales_title_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_sales_creator_1"
android:layout_width="21dp"
android:layout_height="21dp"
android:contentDescription="@null" />
<TextView
android:id="@+id/tv_sales_creator_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5.3dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_777777"
android:textSize="10sp"
tools:ignore="SmallSp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_sales_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="13.3dp"
android:layout_weight="1"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<ImageView
android:id="@+id/iv_sales_2"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_sales_title_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_sales_creator_2"
android:layout_width="21dp"
android:layout_height="21dp"
android:contentDescription="@null" />
<TextView
android:id="@+id/tv_sales_creator_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5.3dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_777777"
android:textSize="10sp"
tools:ignore="SmallSp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_sales_count_top2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:baselineAligned="false"
android:orientation="horizontal"
android:paddingHorizontal="13.3dp"
android:visibility="gone">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
tools:ignore="TooManyViews">
<ImageView
android:id="@+id/iv_sales_count_1"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_sales_count_title_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_sales_count_creator_1"
android:layout_width="21dp"
android:layout_height="21dp"
android:contentDescription="@null" />
<TextView
android:id="@+id/tv_sales_count_creator_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5.3dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_777777"
android:textSize="10sp"
tools:ignore="SmallSp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_sales_count_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="13.3dp"
android:layout_weight="1"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<ImageView
android:id="@+id/iv_sales_count_2"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_sales_count_title_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_sales_count_creator_2"
android:layout_width="21dp"
android:layout_height="21dp"
android:contentDescription="@null" />
<TextView
android:id="@+id/tv_sales_count_creator_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5.3dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_777777"
android:textSize="10sp"
tools:ignore="SmallSp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/ll_no_items" android:id="@+id/ll_no_items"

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" <androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -132,264 +131,13 @@
android:clipToPadding="false" android:clipToPadding="false"
android:paddingHorizontal="13.3dp" /> android:paddingHorizontal="13.3dp" />
<LinearLayout <androidx.recyclerview.widget.RecyclerView
android:id="@+id/ll_sales_top2" android:id="@+id/rv_ranking_sales_count"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="20dp" android:layout_marginTop="20dp"
android:baselineAligned="false" android:clipToPadding="false"
android:orientation="horizontal" android:paddingHorizontal="13.3dp" />
android:paddingHorizontal="13.3dp"
android:visibility="gone">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<ImageView
android:id="@+id/iv_sales_1"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_sales_title_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_sales_creator_1"
android:layout_width="21dp"
android:layout_height="21dp"
android:contentDescription="@null" />
<TextView
android:id="@+id/tv_sales_creator_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5.3dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_777777"
android:textSize="10sp"
tools:ignore="SmallSp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_sales_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="13.3dp"
android:layout_weight="1"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<ImageView
android:id="@+id/iv_sales_2"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_sales_title_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_sales_creator_2"
android:layout_width="21dp"
android:layout_height="21dp"
android:contentDescription="@null" />
<TextView
android:id="@+id/tv_sales_creator_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5.3dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_777777"
android:textSize="10sp"
tools:ignore="SmallSp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_sales_count_top2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:baselineAligned="false"
android:orientation="horizontal"
android:paddingHorizontal="13.3dp"
android:visibility="gone">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
tools:ignore="TooManyViews">
<ImageView
android:id="@+id/iv_sales_count_1"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_sales_count_title_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_sales_count_creator_1"
android:layout_width="21dp"
android:layout_height="21dp"
android:contentDescription="@null" />
<TextView
android:id="@+id/tv_sales_count_creator_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5.3dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_777777"
android:textSize="10sp"
tools:ignore="SmallSp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_sales_count_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="13.3dp"
android:layout_weight="1"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<ImageView
android:id="@+id/iv_sales_count_2"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_sales_count_title_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_sales_count_creator_2"
android:layout_width="21dp"
android:layout_height="21dp"
android:contentDescription="@null" />
<TextView
android:id="@+id/tv_sales_count_creator_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5.3dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_777777"
android:textSize="10sp"
tools:ignore="SmallSp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/ll_no_items" android:id="@+id/ll_no_items"

View File

@ -533,264 +533,13 @@
android:clipToPadding="false" android:clipToPadding="false"
android:paddingHorizontal="13.3dp" /> android:paddingHorizontal="13.3dp" />
<LinearLayout <androidx.recyclerview.widget.RecyclerView
android:id="@+id/ll_sales_top2" android:id="@+id/rv_ranking_sales_count"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="20dp" android:layout_marginTop="20dp"
android:baselineAligned="false" android:clipToPadding="false"
android:orientation="horizontal" android:paddingHorizontal="13.3dp" />
android:paddingHorizontal="13.3dp"
android:visibility="gone">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<ImageView
android:id="@+id/iv_sales_1"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_sales_title_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_sales_creator_1"
android:layout_width="21dp"
android:layout_height="21dp"
android:contentDescription="@null" />
<TextView
android:id="@+id/tv_sales_creator_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5.3dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_777777"
android:textSize="10sp"
tools:ignore="SmallSp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_sales_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="13.3dp"
android:layout_weight="1"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<ImageView
android:id="@+id/iv_sales_2"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_sales_title_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_sales_creator_2"
android:layout_width="21dp"
android:layout_height="21dp"
android:contentDescription="@null" />
<TextView
android:id="@+id/tv_sales_creator_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5.3dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_777777"
android:textSize="10sp"
tools:ignore="SmallSp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_sales_count_top2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:baselineAligned="false"
android:orientation="horizontal"
android:paddingHorizontal="13.3dp"
android:visibility="gone">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
tools:ignore="TooManyViews">
<ImageView
android:id="@+id/iv_sales_count_1"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_sales_count_title_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_sales_count_creator_1"
android:layout_width="21dp"
android:layout_height="21dp"
android:contentDescription="@null" />
<TextView
android:id="@+id/tv_sales_count_creator_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5.3dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_777777"
android:textSize="10sp"
tools:ignore="SmallSp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_sales_count_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="13.3dp"
android:layout_weight="1"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<ImageView
android:id="@+id/iv_sales_count_2"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_sales_count_title_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_sales_count_creator_2"
android:layout_width="21dp"
android:layout_height="21dp"
android:contentDescription="@null" />
<TextView
android:id="@+id/tv_sales_count_creator_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5.3dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_777777"
android:textSize="10sp"
tools:ignore="SmallSp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/ll_no_items" android:id="@+id/ll_no_items"

View File

@ -115,264 +115,13 @@
android:clipToPadding="false" android:clipToPadding="false"
android:paddingHorizontal="13.3dp" /> android:paddingHorizontal="13.3dp" />
<LinearLayout <androidx.recyclerview.widget.RecyclerView
android:id="@+id/ll_sales_top2" android:id="@+id/rv_ranking_sales_count"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="20dp" android:layout_marginTop="20dp"
android:baselineAligned="false" android:clipToPadding="false"
android:orientation="horizontal" android:paddingHorizontal="13.3dp" />
android:paddingHorizontal="13.3dp"
android:visibility="gone">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<ImageView
android:id="@+id/iv_sales_1"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_sales_title_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_sales_creator_1"
android:layout_width="21dp"
android:layout_height="21dp"
android:contentDescription="@null" />
<TextView
android:id="@+id/tv_sales_creator_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5.3dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_777777"
android:textSize="10sp"
tools:ignore="SmallSp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_sales_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="13.3dp"
android:layout_weight="1"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<ImageView
android:id="@+id/iv_sales_2"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_sales_title_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_sales_creator_2"
android:layout_width="21dp"
android:layout_height="21dp"
android:contentDescription="@null" />
<TextView
android:id="@+id/tv_sales_creator_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5.3dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_777777"
android:textSize="10sp"
tools:ignore="SmallSp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_sales_count_top2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:baselineAligned="false"
android:orientation="horizontal"
android:paddingHorizontal="13.3dp"
android:visibility="gone">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
tools:ignore="TooManyViews">
<ImageView
android:id="@+id/iv_sales_count_1"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_sales_count_title_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_sales_count_creator_1"
android:layout_width="21dp"
android:layout_height="21dp"
android:contentDescription="@null" />
<TextView
android:id="@+id/tv_sales_count_creator_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5.3dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_777777"
android:textSize="10sp"
tools:ignore="SmallSp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_sales_count_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="13.3dp"
android:layout_weight="1"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<ImageView
android:id="@+id/iv_sales_count_2"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_sales_count_title_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_sales_count_creator_2"
android:layout_width="21dp"
android:layout_height="21dp"
android:contentDescription="@null" />
<TextView
android:id="@+id/tv_sales_count_creator_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5.3dp"
android:fontFamily="@font/gmarket_sans_medium"
android:textColor="@color/color_777777"
android:textSize="10sp"
tools:ignore="SmallSp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/ll_no_items" android:id="@+id/ll_no_items"

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_cover"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
tools:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:ellipsize="end"
android:fontFamily="@font/gmarket_sans_medium"
android:maxLines="1"
android:textColor="@color/color_d2d2d2"
android:textSize="13.3sp"
tools:text="콘텐츠 제목" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_creator"
android:layout_width="21dp"
android:layout_height="21dp"
android:contentDescription="@null"
tools:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/tv_nickname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5.3dp"
android:ellipsize="end"
android:fontFamily="@font/gmarket_sans_medium"
android:maxLines="1"
android:textColor="@color/color_777777"
android:textSize="10sp"
tools:ignore="SmallSp"
tools:text="크리에이터 닉네임" />
</LinearLayout>
</LinearLayout>