feat: 메인 홈

- 보온 주간 차트 UI 추가
This commit is contained in:
2025-07-15 18:34:46 +09:00
parent 5c4141dad9
commit 76b8b74d41
3 changed files with 208 additions and 0 deletions

View File

@@ -71,6 +71,7 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>(FragmentHomeBinding::infl
private lateinit var originalSeriesAdapter: HomeSeriesAdapter private lateinit var originalSeriesAdapter: HomeSeriesAdapter
private lateinit var auditionAdapter: AuditionBannerAdapter private lateinit var auditionAdapter: AuditionBannerAdapter
private lateinit var seriesDayOfWeekAdapter: HomeSeriesAdapter private lateinit var seriesDayOfWeekAdapter: HomeSeriesAdapter
private lateinit var weelyChartAdapter: HomeWeeklyChartAdapter
private val handler = Handler(Looper.getMainLooper()) private val handler = Handler(Looper.getMainLooper())
@@ -163,6 +164,7 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>(FragmentHomeBinding::infl
setupOriginalSeries() setupOriginalSeries()
setupAudition() setupAudition()
setupSeriesDayOfWeek() setupSeriesDayOfWeek()
setupWeelyChart()
} }
private fun setupLiveView() { private fun setupLiveView() {
@@ -768,6 +770,92 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>(FragmentHomeBinding::infl
rvDayOfWeek.adapter = dayOfWeekAdapter rvDayOfWeek.adapter = dayOfWeekAdapter
} }
private fun setupWeelyChart() {
val spSectionTitle = SpannableString(binding.tvWeeklyChart.text)
spSectionTitle.setSpan(
ForegroundColorSpan(
ContextCompat.getColor(
requireContext(),
R.color.color_3bb9f1
)
),
0,
2,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
binding.tvWeeklyChart.text = spSectionTitle
weelyChartAdapter = HomeWeeklyChartAdapter(
width = screenWidth,
onClickItem = {
startActivity(
Intent(requireContext(), AudioContentDetailActivity::class.java).apply {
putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, it)
}
)
}
)
val recyclerView = binding.rvWeeklyChart
recyclerView.layoutManager = GridLayoutManager(
context,
4,
GridLayoutManager.HORIZONTAL,
false
)
weelyChartAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
override fun onChanged() {
if (weelyChartAdapter.itemCount < 2) {
recyclerView.layoutManager =
LinearLayoutManager(recyclerView.context, RecyclerView.HORIZONTAL, false)
} else if (weelyChartAdapter.itemCount < 3) {
recyclerView.layoutManager =
GridLayoutManager(recyclerView.context, 2, RecyclerView.HORIZONTAL, false)
} else if (weelyChartAdapter.itemCount < 4) {
recyclerView.layoutManager =
GridLayoutManager(recyclerView.context, 3, RecyclerView.HORIZONTAL, false)
} else {
recyclerView.layoutManager =
GridLayoutManager(recyclerView.context, 4, RecyclerView.HORIZONTAL, false)
}
}
})
recyclerView.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 || position == 2 || position == 3) {
outRect.left = 0f.dpToPx().toInt()
} else {
outRect.left = 8f.dpToPx().toInt()
}
outRect.right = 8f.dpToPx().toInt()
}
})
recyclerView.adapter = weelyChartAdapter
viewModel.contentRankingLiveData.observe(viewLifecycleOwner) {
if (it.isNotEmpty()) {
binding.llWeeklyChart.visibility = View.VISIBLE
weelyChartAdapter.addItems(it)
} else {
binding.llWeeklyChart.visibility = View.GONE
}
}
}
private fun bindData() { private fun bindData() {
viewModel.isLoading.observe(viewLifecycleOwner) { viewModel.isLoading.observe(viewLifecycleOwner) {
if (it) { if (it) {

View File

@@ -0,0 +1,67 @@
package kr.co.vividnext.sodalive.home
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import coil.load
import coil.transform.RoundedCornersTransformation
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRankingItem
import kr.co.vividnext.sodalive.databinding.ItemHomeContentRankingBinding
import kr.co.vividnext.sodalive.extensions.dpToPx
class HomeWeeklyChartAdapter(
private val width: Int,
private val onClickItem: (Long) -> Unit
) : RecyclerView.Adapter<HomeWeeklyChartAdapter.ViewHolder>() {
private val items = mutableListOf<GetAudioContentRankingItem>()
inner class ViewHolder(
private val binding: ItemHomeContentRankingBinding
) : RecyclerView.ViewHolder(binding.root) {
@SuppressLint("SetTextI18n")
fun bind(item: GetAudioContentRankingItem, index: Int) {
val lp = binding.root.layoutParams
lp.width = width * 282 / 400
lp.height = 60f.dpToPx().toInt()
binding.root.layoutParams = lp
binding.root.setOnClickListener { onClickItem(item.contentId) }
binding.tvTitle.text = item.title
binding.tvRank.text = "${index + 1}"
binding.tvNickname.text = item.creatorNickname
binding.ivCover.load(item.coverImageUrl) {
crossfade(true)
placeholder(R.drawable.ic_place_holder)
transformations(RoundedCornersTransformation(12f.dpToPx()))
}
}
}
@SuppressLint("NotifyDataSetChanged")
fun addItems(items: List<GetAudioContentRankingItem>) {
this.items.clear()
this.items.addAll(items)
notifyDataSetChanged()
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
) = ViewHolder(
ItemHomeContentRankingBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
override fun getItemCount() = items.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(items[position], index = position)
}
}

View File

@@ -0,0 +1,53 @@
<?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:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<TextView
android:id="@+id/tv_rank"
android:layout_width="30dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:fontFamily="@font/pretendard_bold"
android:gravity="center"
android:textColor="#B5E7FA"
android:textSize="24sp"
tools:text="10" />
<ImageView
android:id="@+id/iv_cover"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginEnd="16dp"
android:contentDescription="@null" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/pretendard_regular"
android:maxLines="1"
android:textColor="@color/white"
android:textSize="18sp"
tools:text="라일락 꽃 향기 맡으며" />
<TextView
android:id="@+id/tv_nickname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:fontFamily="@font/pretendard_regular"
android:textColor="#78909C"
android:textSize="14sp"
tools:text="J Fla" />
</LinearLayout>
</LinearLayout>