콘텐츠 메인 ASMR 탭

- 채널별 추천 ASMR 추가
This commit is contained in:
klaus 2025-02-15 02:53:40 +09:00
parent 022b51488f
commit 28ec227658
6 changed files with 546 additions and 0 deletions

View File

@ -333,6 +333,12 @@ interface AudioContentApi {
@Header("Authorization") authHeader: String @Header("Authorization") authHeader: String
): Single<ApiResponse<GetContentMainTabAsmrResponse>> ): Single<ApiResponse<GetContentMainTabAsmrResponse>>
@GET("/v2/audio-content/main/asmr/popular-content-by-creator")
fun getPopularAsmrContentByCreator(
@Query("creatorId") creatorId: Long,
@Header("Authorization") authHeader: String
): Single<ApiResponse<GetPopularContentByCreatorResponse>>
@GET("/v2/audio-content/main/replay") @GET("/v2/audio-content/main/replay")
fun getContentMainReplay( fun getContentMainReplay(
@Header("Authorization") authHeader: String @Header("Authorization") authHeader: String

View File

@ -6,7 +6,9 @@ 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
@ -14,6 +16,9 @@ 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
@ -21,9 +26,11 @@ 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.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
@ -48,6 +55,7 @@ class AudioContentMainTabAsmrFragment : BaseFragment<FragmentAudioContentMainTab
private lateinit var newContentAdapter: AudioContentMainContentAdapter private lateinit var newContentAdapter: AudioContentMainContentAdapter
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
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
@ -63,6 +71,7 @@ class AudioContentMainTabAsmrFragment : BaseFragment<FragmentAudioContentMainTab
setupContentBanner() setupContentBanner()
setupNewContent() setupNewContent()
setupContentRanking() setupContentRanking()
setupPopularContentByCreator()
setupEventBanner() setupEventBanner()
setupCuration() setupCuration()
} }
@ -380,6 +389,66 @@ class AudioContentMainTabAsmrFragment : BaseFragment<FragmentAudioContentMainTab
} }
} }
private fun setupPopularContentByCreator() {
contentRankCreatorAdapter = ContentRankCreatorAdapter {
loadingPopularContentByCreator()
viewModel.getPopularContentByCreator(it)
}
binding.rvRankingCreator.layoutManager = LinearLayoutManager(
context,
LinearLayoutManager.HORIZONTAL,
false
)
binding.rvRankingCreator.addItemDecoration(object : RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
super.getItemOffsets(outRect, view, parent, state)
when (parent.getChildAdapterPosition(view)) {
0 -> {
outRect.left = 0
outRect.right = 4f.dpToPx().toInt()
}
contentRankCreatorAdapter.itemCount - 1 -> {
outRect.left = 4f.dpToPx().toInt()
outRect.right = 0
}
else -> {
outRect.left = 4f.dpToPx().toInt()
outRect.right = 4f.dpToPx().toInt()
}
}
}
})
binding.rvRankingCreator.adapter = contentRankCreatorAdapter
viewModel.contentCreatorListLiveData.observe(viewLifecycleOwner) {
contentRankCreatorAdapter.addItems(it)
if (contentRankCreatorAdapter.itemCount <= 0 && it.isEmpty()) {
binding.llCreatorContentRanking.visibility = View.GONE
} else {
binding.llCreatorContentRanking.visibility = View.VISIBLE
}
}
}
private fun loadingPopularContentByCreator() {
binding.llSales2.visibility = View.GONE
binding.llSalesTop2.visibility = View.GONE
binding.llSalesCount2.visibility = View.GONE
binding.llSalesCountTop2.visibility = View.GONE
binding.llNoItems.visibility = View.VISIBLE
}
private fun bindData() { private fun bindData() {
viewModel.toastLiveData.observe(viewLifecycleOwner) { viewModel.toastLiveData.observe(viewLifecycleOwner) {
it?.let { Toast.makeText(requireContext(), it, Toast.LENGTH_LONG).show() } it?.let { Toast.makeText(requireContext(), it, Toast.LENGTH_LONG).show() }
@ -392,5 +461,94 @@ 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

@ -4,4 +4,8 @@ import kr.co.vividnext.sodalive.audio_content.AudioContentApi
class AudioContentMainTabAsmrRepository(private val api: AudioContentApi) { class AudioContentMainTabAsmrRepository(private val api: AudioContentApi) {
fun getContentMainAsmr(token: String) = api.getContentMainAsmr(authHeader = token) fun getContentMainAsmr(token: String) = api.getContentMainAsmr(authHeader = token)
fun getPopularContentByCreator(
creatorId: Long,
token: String
) = api.getPopularAsmrContentByCreator(creatorId, authHeader = token)
} }

View File

@ -5,6 +5,7 @@ import androidx.lifecycle.MutableLiveData
import com.orhanobut.logger.Logger import com.orhanobut.logger.Logger
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.schedulers.Schedulers
import kr.co.vividnext.sodalive.audio_content.main.ContentCreatorResponse
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentBannerResponse import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentBannerResponse
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.GetAudioContentRankingItem import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRankingItem
@ -36,6 +37,19 @@ class AudioContentMainTabAsmrViewModel(
val contentRankingLiveData: LiveData<List<GetAudioContentRankingItem>> val contentRankingLiveData: LiveData<List<GetAudioContentRankingItem>>
get() = _contentRankingLiveData get() = _contentRankingLiveData
private val _contentCreatorListLiveData = MutableLiveData<List<ContentCreatorResponse>>()
val contentCreatorListLiveData: LiveData<List<ContentCreatorResponse>>
get() = _contentCreatorListLiveData
private val _salesRankContentListLiveData = MutableLiveData<List<GetAudioContentRankingItem>>()
val salesRankContentListLiveData: LiveData<List<GetAudioContentRankingItem>>
get() = _salesRankContentListLiveData
private val _salesCountRankContentListLiveData =
MutableLiveData<List<GetAudioContentRankingItem>>()
val salesCountRankContentListLiveData: LiveData<List<GetAudioContentRankingItem>>
get() = _salesCountRankContentListLiveData
private val _eventLiveData = MutableLiveData<List<EventItem>>() private val _eventLiveData = MutableLiveData<List<EventItem>>()
val eventLiveData: LiveData<List<EventItem>> val eventLiveData: LiveData<List<EventItem>>
get() = _eventLiveData get() = _eventLiveData
@ -58,6 +72,10 @@ class AudioContentMainTabAsmrViewModel(
_contentBannerLiveData.value = data.contentBannerList _contentBannerLiveData.value = data.contentBannerList
_newContentListLiveData.value = data.newAsmrContentList _newContentListLiveData.value = data.newAsmrContentList
_contentRankingLiveData.value = data.rankAsmrContentList _contentRankingLiveData.value = data.rankAsmrContentList
_contentCreatorListLiveData.value = data.creatorList
_salesRankContentListLiveData.value = data.salesRankContentList
_salesCountRankContentListLiveData.value =
data.salesCountRankContentList
_eventLiveData.value = data.eventBannerList.eventList _eventLiveData.value = data.eventBannerList.eventList
_curationListLiveData.value = data.curationList _curationListLiveData.value = data.curationList
} else { } else {
@ -80,4 +98,40 @@ class AudioContentMainTabAsmrViewModel(
) )
) )
} }
fun getPopularContentByCreator(creatorId: Long) {
_isLoading.value = true
compositeDisposable.add(
repository.getPopularContentByCreator(
creatorId = creatorId,
token = "Bearer ${SharedPreferenceManager.token}"
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{
_isLoading.value = false
if (it.success && it.data != null) {
val data = it.data
_salesRankContentListLiveData.value = data.salesRankContentList
_salesCountRankContentListLiveData.value =
data.salesCountRankContentList
} else {
if (it.message != null) {
_toastLiveData.postValue(it.message)
} else {
_toastLiveData.postValue(
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
)
}
}
},
{
_isLoading.value = false
it.message?.let { message -> Logger.e(message) }
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
}
)
)
}
} }

View File

@ -2,6 +2,7 @@ package kr.co.vividnext.sodalive.audio_content.main.v2.asmr
import androidx.annotation.Keep import androidx.annotation.Keep
import com.google.gson.annotations.SerializedName import com.google.gson.annotations.SerializedName
import kr.co.vividnext.sodalive.audio_content.main.ContentCreatorResponse
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentBannerResponse import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentBannerResponse
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.GetAudioContentRankingItem import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRankingItem
@ -16,6 +17,12 @@ data class GetContentMainTabAsmrResponse(
val newAsmrContentList: List<GetAudioContentMainItem>, val newAsmrContentList: List<GetAudioContentMainItem>,
@SerializedName("rankAsmrContentList") @SerializedName("rankAsmrContentList")
val rankAsmrContentList: List<GetAudioContentRankingItem>, val rankAsmrContentList: List<GetAudioContentRankingItem>,
@SerializedName("creatorList")
val creatorList: List<ContentCreatorResponse>,
@SerializedName("salesRankContentList")
val salesRankContentList: List<GetAudioContentRankingItem>,
@SerializedName("salesCountRankContentList")
val salesCountRankContentList: List<GetAudioContentRankingItem>,
@SerializedName("eventBannerList") @SerializedName("eventBannerList")
val eventBannerList: GetEventResponse, val eventBannerList: GetEventResponse,
@SerializedName("curationList") @SerializedName("curationList")

View File

@ -1,5 +1,7 @@
<?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"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
@ -88,6 +90,321 @@
android:paddingHorizontal="6.7dp" /> android:paddingHorizontal="6.7dp" />
</LinearLayout> </LinearLayout>
<LinearLayout
android:id="@+id/ll_creator_content_ranking"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:orientation="vertical"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="13.3dp"
android:fontFamily="@font/gmarket_sans_bold"
android:text="채널별 추천 ASMR"
android:textColor="@color/color_eeeeee"
android:textSize="18.3sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_ranking_creator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:clipToPadding="false"
android:paddingHorizontal="13.3dp" />
<LinearLayout
android:id="@+id/ll_sales_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">
<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
android:id="@+id/ll_no_items"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="13.3dp"
android:layout_marginTop="28.3dp"
android:background="@drawable/bg_round_corner_4_7_13181b"
android:gravity="center"
android:orientation="vertical"
android:paddingVertical="16.7dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/ic_no_item" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginVertical="10dp"
android:fontFamily="@font/gmarket_sans_medium"
android:gravity="center"
android:lineSpacingExtra="8dp"
android:text="마이페이지에서 본인인증을 해주세요"
android:textColor="@color/color_bbbbbb"
android:textSize="13sp"
tools:ignore="SmallSp" />
</LinearLayout>
</LinearLayout>
<com.zhpan.bannerview.BannerViewPager <com.zhpan.bannerview.BannerViewPager
android:id="@+id/event_banner_slider" android:id="@+id/event_banner_slider"
android:layout_width="match_parent" android:layout_width="match_parent"