feat: 메인 홈
- 큐레이션 UI 추가
This commit is contained in:
@@ -0,0 +1,100 @@
|
|||||||
|
package kr.co.vividnext.sodalive.home
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Rect
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentMainItem
|
||||||
|
import kr.co.vividnext.sodalive.audio_content.main.v2.GetContentCurationResponse
|
||||||
|
import kr.co.vividnext.sodalive.databinding.ItemHomeCurationBinding
|
||||||
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
|
|
||||||
|
class HomeCurationAdapter(
|
||||||
|
private val onClickItem: (Long) -> Unit
|
||||||
|
) : RecyclerView.Adapter<HomeCurationAdapter.ViewHolder>() {
|
||||||
|
|
||||||
|
private val items = mutableListOf<GetContentCurationResponse>()
|
||||||
|
|
||||||
|
inner class ViewHolder(
|
||||||
|
private val context: Context,
|
||||||
|
private val binding: ItemHomeCurationBinding
|
||||||
|
) : RecyclerView.ViewHolder(binding.root) {
|
||||||
|
fun bind(item: GetContentCurationResponse) {
|
||||||
|
binding.tvTitle.text = item.title
|
||||||
|
setAudioContentList(item.items)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setAudioContentList(audioContents: List<GetAudioContentMainItem>) {
|
||||||
|
val adapter = HomeContentAdapter(onClickItem)
|
||||||
|
|
||||||
|
binding.rvCuration.layoutManager = LinearLayoutManager(
|
||||||
|
context,
|
||||||
|
LinearLayoutManager.HORIZONTAL,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
if (binding.rvCuration.itemDecorationCount == 0) {
|
||||||
|
binding.rvCuration.addItemDecoration(object : RecyclerView.ItemDecoration() {
|
||||||
|
override fun getItemOffsets(
|
||||||
|
outRect: Rect,
|
||||||
|
view: View,
|
||||||
|
parent: RecyclerView,
|
||||||
|
state: RecyclerView.State
|
||||||
|
) {
|
||||||
|
super.getItemOffsets(outRect, view, parent, state)
|
||||||
|
outRect.top = 8f.dpToPx().toInt()
|
||||||
|
outRect.bottom = 8f.dpToPx().toInt()
|
||||||
|
|
||||||
|
val position = parent.getChildAdapterPosition(view)
|
||||||
|
|
||||||
|
if (position == 0 || position == 1) {
|
||||||
|
outRect.left = 0f.dpToPx().toInt()
|
||||||
|
} else {
|
||||||
|
outRect.left = 8f.dpToPx().toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
outRect.right = 8f.dpToPx().toInt()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
binding.rvCuration.adapter = adapter
|
||||||
|
adapter.addItems(
|
||||||
|
audioContents.map {
|
||||||
|
AudioContentMainItem(
|
||||||
|
contentId = it.contentId,
|
||||||
|
creatorId = it.creatorId,
|
||||||
|
title = it.title,
|
||||||
|
coverImageUrl = it.coverImageUrl,
|
||||||
|
creatorNickname = it.creatorNickname,
|
||||||
|
isPointAvailable = it.isPointAvailable
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
|
||||||
|
parent.context,
|
||||||
|
ItemHomeCurationBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
|
holder.bind(items[position])
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount() = items.size
|
||||||
|
|
||||||
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
|
fun addItems(items: List<GetContentCurationResponse>) {
|
||||||
|
this.items.clear()
|
||||||
|
this.items.addAll(items)
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -73,6 +73,7 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>(FragmentHomeBinding::infl
|
|||||||
private lateinit var seriesDayOfWeekAdapter: HomeSeriesAdapter
|
private lateinit var seriesDayOfWeekAdapter: HomeSeriesAdapter
|
||||||
private lateinit var weelyChartAdapter: HomeWeeklyChartAdapter
|
private lateinit var weelyChartAdapter: HomeWeeklyChartAdapter
|
||||||
private lateinit var homeFreeContentAdapter: HomeContentAdapter
|
private lateinit var homeFreeContentAdapter: HomeContentAdapter
|
||||||
|
private lateinit var curationAdapter: HomeCurationAdapter
|
||||||
|
|
||||||
private val handler = Handler(Looper.getMainLooper())
|
private val handler = Handler(Looper.getMainLooper())
|
||||||
|
|
||||||
@@ -167,6 +168,7 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>(FragmentHomeBinding::infl
|
|||||||
setupSeriesDayOfWeek()
|
setupSeriesDayOfWeek()
|
||||||
setupWeelyChart()
|
setupWeelyChart()
|
||||||
setupFreeContent()
|
setupFreeContent()
|
||||||
|
setupCuration()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupLiveView() {
|
private fun setupLiveView() {
|
||||||
@@ -917,6 +919,63 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>(FragmentHomeBinding::infl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setupCuration() {
|
||||||
|
curationAdapter = HomeCurationAdapter(
|
||||||
|
onClickItem = {
|
||||||
|
startActivity(
|
||||||
|
Intent(requireContext(), AudioContentDetailActivity::class.java).apply {
|
||||||
|
putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, it)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
binding.rvCuration.layoutManager = LinearLayoutManager(
|
||||||
|
context,
|
||||||
|
LinearLayoutManager.VERTICAL,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
binding.rvCuration.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.top = 48f.dpToPx().toInt()
|
||||||
|
outRect.bottom = 24f.dpToPx().toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
curationAdapter.itemCount - 1 -> {
|
||||||
|
outRect.top = 24f.dpToPx().toInt()
|
||||||
|
outRect.bottom = 48f.dpToPx().toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
outRect.top = 24f.dpToPx().toInt()
|
||||||
|
outRect.bottom = 24f.dpToPx().toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
binding.rvCuration.adapter = curationAdapter
|
||||||
|
|
||||||
|
viewModel.curationListLiveData.observe(viewLifecycleOwner) {
|
||||||
|
if (it.isNotEmpty()) {
|
||||||
|
binding.rvCuration.visibility = View.VISIBLE
|
||||||
|
curationAdapter.addItems(it)
|
||||||
|
} else {
|
||||||
|
binding.rvCuration.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun bindData() {
|
private fun bindData() {
|
||||||
viewModel.isLoading.observe(viewLifecycleOwner) {
|
viewModel.isLoading.observe(viewLifecycleOwner) {
|
||||||
if (it) {
|
if (it) {
|
||||||
|
|||||||
29
app/src/main/res/layout/item_home_curation.xml
Normal file
29
app/src/main/res/layout/item_home_curation.xml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<androidx.constraintlayout.widget.ConstraintLayout 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_height="wrap_content">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_title"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="24dp"
|
||||||
|
android:fontFamily="@font/pretendard_bold"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="26sp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="큐레이션" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/rv_curation"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:paddingHorizontal="24dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/tv_title" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
Reference in New Issue
Block a user