feat: 메인 홈
- 오직 보이스온에서만 UI 추가
This commit is contained in:
		@@ -67,7 +67,7 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>(FragmentHomeBinding::infl
 | 
			
		||||
 | 
			
		||||
    private lateinit var homeContentAdapter: HomeContentAdapter
 | 
			
		||||
    private lateinit var contentBannerAdapter: AudioContentMainBannerAdapter
 | 
			
		||||
    private lateinit var seriesAdapter: HomeSeriesAdapter
 | 
			
		||||
    private lateinit var originalSeriesAdapter: HomeSeriesAdapter
 | 
			
		||||
 | 
			
		||||
    private val handler = Handler(Looper.getMainLooper())
 | 
			
		||||
 | 
			
		||||
@@ -157,6 +157,7 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>(FragmentHomeBinding::infl
 | 
			
		||||
        setupSectionCreator()
 | 
			
		||||
        setupLatestContent()
 | 
			
		||||
        setupContentBanner()
 | 
			
		||||
        setupOriginalSeries()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun setupLiveView() {
 | 
			
		||||
@@ -525,6 +526,73 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>(FragmentHomeBinding::infl
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun setupOriginalSeries() {
 | 
			
		||||
        val spSectionTitle = SpannableString(binding.tvSeriesOriginal.text)
 | 
			
		||||
        spSectionTitle.setSpan(
 | 
			
		||||
            ForegroundColorSpan(
 | 
			
		||||
                ContextCompat.getColor(
 | 
			
		||||
                    requireContext(),
 | 
			
		||||
                    R.color.color_3bb9f1
 | 
			
		||||
                )
 | 
			
		||||
            ),
 | 
			
		||||
            0,
 | 
			
		||||
            2,
 | 
			
		||||
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
 | 
			
		||||
        )
 | 
			
		||||
        binding.tvSeriesOriginal.text = spSectionTitle
 | 
			
		||||
 | 
			
		||||
        originalSeriesAdapter = HomeSeriesAdapter {
 | 
			
		||||
            startActivity(
 | 
			
		||||
                Intent(requireContext(), SeriesDetailActivity::class.java).apply {
 | 
			
		||||
                    putExtra(Constants.EXTRA_SERIES_ID, it)
 | 
			
		||||
                }
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        val recyclerView = binding.rvSeriesOriginal
 | 
			
		||||
        recyclerView.layoutManager = LinearLayoutManager(
 | 
			
		||||
            context,
 | 
			
		||||
            LinearLayoutManager.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)
 | 
			
		||||
 | 
			
		||||
                when (parent.getChildAdapterPosition(view)) {
 | 
			
		||||
                    0 -> {
 | 
			
		||||
                        outRect.left = 0
 | 
			
		||||
                        outRect.right = 8f.dpToPx().toInt()
 | 
			
		||||
                    }
 | 
			
		||||
                    originalSeriesAdapter.itemCount - 1 -> {
 | 
			
		||||
                        outRect.left = 8f.dpToPx().toInt()
 | 
			
		||||
                        outRect.right = 0
 | 
			
		||||
                    }
 | 
			
		||||
                    else -> {
 | 
			
		||||
                        outRect.left = 8f.dpToPx().toInt()
 | 
			
		||||
                        outRect.right = 8f.dpToPx().toInt()
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        recyclerView.adapter = originalSeriesAdapter
 | 
			
		||||
 | 
			
		||||
        viewModel.originalAudioDramaListLiveData.observe(viewLifecycleOwner) {
 | 
			
		||||
            if (it.isNotEmpty()) {
 | 
			
		||||
                binding.llSeriesOriginal.visibility = View.VISIBLE
 | 
			
		||||
                originalSeriesAdapter.addItems(it)
 | 
			
		||||
            } else {
 | 
			
		||||
                binding.llSeriesOriginal.visibility = View.GONE
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun bindData() {
 | 
			
		||||
        viewModel.isLoading.observe(viewLifecycleOwner) {
 | 
			
		||||
            if (it) {
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,89 @@
 | 
			
		||||
package kr.co.vividnext.sodalive.home
 | 
			
		||||
 | 
			
		||||
import android.annotation.SuppressLint
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.view.LayoutInflater
 | 
			
		||||
import android.view.View
 | 
			
		||||
import android.view.ViewGroup
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView
 | 
			
		||||
import com.bumptech.glide.Glide
 | 
			
		||||
import com.bumptech.glide.load.resource.bitmap.CenterCrop
 | 
			
		||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
 | 
			
		||||
import com.bumptech.glide.request.RequestOptions
 | 
			
		||||
import kr.co.vividnext.sodalive.audio_content.series.GetSeriesListResponse
 | 
			
		||||
import kr.co.vividnext.sodalive.databinding.ItemHomeSeriesBinding
 | 
			
		||||
import kr.co.vividnext.sodalive.extensions.dpToPx
 | 
			
		||||
 | 
			
		||||
class HomeSeriesAdapter(
 | 
			
		||||
    private val onClickItem: (Long) -> Unit
 | 
			
		||||
) : RecyclerView.Adapter<HomeSeriesAdapter.ViewHolder>() {
 | 
			
		||||
 | 
			
		||||
    val items = mutableListOf<GetSeriesListResponse.SeriesListItem>()
 | 
			
		||||
 | 
			
		||||
    inner class ViewHolder(
 | 
			
		||||
        private val context: Context,
 | 
			
		||||
        private val binding: ItemHomeSeriesBinding
 | 
			
		||||
    ) : RecyclerView.ViewHolder(binding.root) {
 | 
			
		||||
        @SuppressLint("SetTextI18n")
 | 
			
		||||
        fun bind(item: GetSeriesListResponse.SeriesListItem) {
 | 
			
		||||
            Glide
 | 
			
		||||
                .with(context)
 | 
			
		||||
                .load(item.coverImage)
 | 
			
		||||
                .apply(
 | 
			
		||||
                    RequestOptions().transform(
 | 
			
		||||
                        CenterCrop(),
 | 
			
		||||
                        RoundedCorners(16f.dpToPx().toInt())
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
                .into(binding.ivCover)
 | 
			
		||||
 | 
			
		||||
            binding.tvTitle.text = item.title
 | 
			
		||||
            binding.tvNickname.text = item.creator.nickname
 | 
			
		||||
            binding.tvSeriesContentCount.text = "총 ${item.numberOfContent}화"
 | 
			
		||||
            binding.tvNew.visibility = if (item.isNew) {
 | 
			
		||||
                View.VISIBLE
 | 
			
		||||
            } else {
 | 
			
		||||
                View.GONE
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            binding.tvPopular.visibility = if (item.isPopular) {
 | 
			
		||||
                View.VISIBLE
 | 
			
		||||
            } else {
 | 
			
		||||
                View.GONE
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (item.isComplete) {
 | 
			
		||||
                binding.tvComplete.visibility = View.VISIBLE
 | 
			
		||||
            } else {
 | 
			
		||||
                binding.tvComplete.visibility = View.GONE
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            binding.root.setOnClickListener { onClickItem(item.seriesId) }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
 | 
			
		||||
        parent.context,
 | 
			
		||||
        ItemHomeSeriesBinding.inflate(
 | 
			
		||||
            LayoutInflater.from(parent.context),
 | 
			
		||||
            parent,
 | 
			
		||||
            false
 | 
			
		||||
        )
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
 | 
			
		||||
        holder.bind(items[position])
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun getItemCount() = items.count()
 | 
			
		||||
 | 
			
		||||
    @SuppressLint("NotifyDataSetChanged")
 | 
			
		||||
    fun addItems(items: List<GetSeriesListResponse.SeriesListItem>) {
 | 
			
		||||
        this.items.addAll(items)
 | 
			
		||||
        notifyDataSetChanged()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun isVisibleRecyclerView(): Boolean {
 | 
			
		||||
        return items.isNotEmpty()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
 | 
			
		||||
    <solid android:color="#b2000000" />
 | 
			
		||||
    <corners
 | 
			
		||||
        android:bottomRightRadius="16dp"
 | 
			
		||||
        android:topLeftRadius="16dp" />
 | 
			
		||||
</shape>
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
 | 
			
		||||
    <solid android:color="#ef5247" />
 | 
			
		||||
    <corners
 | 
			
		||||
        android:bottomRightRadius="16dp"
 | 
			
		||||
        android:topLeftRadius="16dp" />
 | 
			
		||||
</shape>
 | 
			
		||||
@@ -0,0 +1,14 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
 | 
			
		||||
    <gradient
 | 
			
		||||
        android:type="linear"
 | 
			
		||||
        android:angle="270"
 | 
			
		||||
        android:startColor="#0001B1"
 | 
			
		||||
        android:centerColor="#0001B1"
 | 
			
		||||
        android:endColor="#3B5FF1"
 | 
			
		||||
        android:centerY="0.24" />
 | 
			
		||||
 | 
			
		||||
    <corners
 | 
			
		||||
        android:bottomRightRadius="16dp"
 | 
			
		||||
        android:topLeftRadius="16dp" />
 | 
			
		||||
</shape>
 | 
			
		||||
@@ -0,0 +1,8 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
 | 
			
		||||
    <solid android:color="@android:color/transparent" />
 | 
			
		||||
    <corners android:radius="39dp" />
 | 
			
		||||
    <stroke
 | 
			
		||||
        android:width="1dp"
 | 
			
		||||
        android:color="@color/white" />
 | 
			
		||||
</shape>
 | 
			
		||||
							
								
								
									
										112
									
								
								app/src/main/res/layout/item_home_series.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								app/src/main/res/layout/item_home_series.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,112 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<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="wrap_content"
 | 
			
		||||
    android:layout_height="wrap_content">
 | 
			
		||||
 | 
			
		||||
    <ImageView
 | 
			
		||||
        android:id="@+id/iv_cover"
 | 
			
		||||
        android:layout_width="160dp"
 | 
			
		||||
        android:layout_height="227dp"
 | 
			
		||||
        android:contentDescription="@null"
 | 
			
		||||
        android:scaleType="centerCrop"
 | 
			
		||||
        app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
        app:layout_constraintTop_toTopOf="parent"
 | 
			
		||||
        tools:src="@drawable/ic_launcher_background" />
 | 
			
		||||
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
        android:layout_width="0dp"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:orientation="horizontal"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="@+id/iv_cover"
 | 
			
		||||
        app:layout_constraintTop_toTopOf="@+id/iv_cover">
 | 
			
		||||
 | 
			
		||||
        <TextView
 | 
			
		||||
            android:id="@+id/tv_popular"
 | 
			
		||||
            android:layout_width="wrap_content"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:background="@drawable/bg_left_top_right_bottom_round_corner_16_ef5247"
 | 
			
		||||
            android:fontFamily="@font/pretendard_regular"
 | 
			
		||||
            android:paddingHorizontal="10dp"
 | 
			
		||||
            android:paddingVertical="3dp"
 | 
			
		||||
            android:text="인기"
 | 
			
		||||
            android:textColor="@color/white"
 | 
			
		||||
            android:textSize="12sp"
 | 
			
		||||
            android:visibility="gone" />
 | 
			
		||||
 | 
			
		||||
        <TextView
 | 
			
		||||
            android:id="@+id/tv_new"
 | 
			
		||||
            android:layout_width="wrap_content"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:background="@drawable/bg_left_top_right_bottom_round_corner_16_gradient"
 | 
			
		||||
            android:fontFamily="@font/pretendard_regular"
 | 
			
		||||
            android:paddingHorizontal="10dp"
 | 
			
		||||
            android:paddingVertical="3dp"
 | 
			
		||||
            android:text="신작"
 | 
			
		||||
            android:textColor="@color/white"
 | 
			
		||||
            android:textSize="12sp"
 | 
			
		||||
            android:visibility="gone"
 | 
			
		||||
            tools:ignore="SmallSp" />
 | 
			
		||||
 | 
			
		||||
        <TextView
 | 
			
		||||
            android:id="@+id/tv_complete"
 | 
			
		||||
            android:layout_width="wrap_content"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:background="@drawable/bg_left_top_right_bottom_round_corner_16_black_70"
 | 
			
		||||
            android:fontFamily="@font/pretendard_regular"
 | 
			
		||||
            android:paddingHorizontal="10dp"
 | 
			
		||||
            android:paddingVertical="3dp"
 | 
			
		||||
            android:text="완결"
 | 
			
		||||
            android:textColor="@color/white"
 | 
			
		||||
            android:textSize="12sp"
 | 
			
		||||
            android:visibility="gone" />
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
 | 
			
		||||
    <TextView
 | 
			
		||||
        android:id="@+id/tv_series_content_count"
 | 
			
		||||
        android:layout_width="wrap_content"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:layout_marginEnd="8dp"
 | 
			
		||||
        android:layout_marginBottom="8dp"
 | 
			
		||||
        android:background="@drawable/bg_round_corner_39_transparent_white"
 | 
			
		||||
        android:fontFamily="@font/pretendard_regular"
 | 
			
		||||
        android:paddingHorizontal="10dp"
 | 
			
		||||
        android:paddingVertical="3dp"
 | 
			
		||||
        android:textColor="@color/white"
 | 
			
		||||
        android:textSize="12sp"
 | 
			
		||||
        app:layout_constraintBottom_toBottomOf="@+id/iv_cover"
 | 
			
		||||
        app:layout_constraintEnd_toEndOf="@+id/iv_cover"
 | 
			
		||||
        tools:text="총 24화" />
 | 
			
		||||
 | 
			
		||||
    <TextView
 | 
			
		||||
        android:id="@+id/tv_title"
 | 
			
		||||
        android:layout_width="0dp"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:layout_marginTop="4dp"
 | 
			
		||||
        android:ellipsize="end"
 | 
			
		||||
        android:fontFamily="@font/pretendard_regular"
 | 
			
		||||
        android:maxLines="1"
 | 
			
		||||
        android:textColor="#b0bec5"
 | 
			
		||||
        android:textSize="18sp"
 | 
			
		||||
        app:layout_constraintEnd_toEndOf="@+id/iv_cover"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="@+id/iv_cover"
 | 
			
		||||
        app:layout_constraintTop_toBottomOf="@+id/iv_cover"
 | 
			
		||||
        tools:text="제목, 관심사,프로필+방장, 참여인원(어딘가..)" />
 | 
			
		||||
 | 
			
		||||
    <TextView
 | 
			
		||||
        android:id="@+id/tv_nickname"
 | 
			
		||||
        android:layout_width="0dp"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:layout_marginTop="4dp"
 | 
			
		||||
        android:ellipsize="end"
 | 
			
		||||
        android:fontFamily="@font/pretendard_regular"
 | 
			
		||||
        android:maxLines="1"
 | 
			
		||||
        android:textColor="#78909C"
 | 
			
		||||
        android:textSize="14sp"
 | 
			
		||||
        app:layout_constraintEnd_toEndOf="@+id/iv_cover"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="@+id/iv_cover"
 | 
			
		||||
        app:layout_constraintTop_toBottomOf="@+id/tv_title"
 | 
			
		||||
        tools:text="설린" />
 | 
			
		||||
</androidx.constraintlayout.widget.ConstraintLayout>
 | 
			
		||||
		Reference in New Issue
	
	Block a user