feat(home): 첫 오디오 콘텐츠 카드를 정리한다
This commit is contained in:
@@ -1,13 +1,20 @@
|
|||||||
package kr.co.vividnext.sodalive.v2.main.home.ui
|
package kr.co.vividnext.sodalive.v2.main.home.ui
|
||||||
|
|
||||||
|
import android.graphics.Outline
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.view.ViewOutlineProvider
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.TextView
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import kr.co.vividnext.sodalive.R
|
import kr.co.vividnext.sodalive.R
|
||||||
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
import kr.co.vividnext.sodalive.extensions.loadUrl
|
import kr.co.vividnext.sodalive.extensions.loadUrl
|
||||||
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationFirstAudioContentUiModel
|
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationFirstAudioContentUiModel
|
||||||
import kr.co.vividnext.sodalive.v2.widget.AudioContentCardSize
|
import kr.co.vividnext.sodalive.v2.widget.AudioContentTag
|
||||||
import kr.co.vividnext.sodalive.v2.widget.AudioContentCardView
|
|
||||||
|
|
||||||
class HomeFirstAudioAdapter : RecyclerView.Adapter<HomeFirstAudioAdapter.AudioViewHolder>() {
|
class HomeFirstAudioAdapter : RecyclerView.Adapter<HomeFirstAudioAdapter.AudioViewHolder>() {
|
||||||
private var items: List<HomeRecommendationFirstAudioContentUiModel> = emptyList()
|
private var items: List<HomeRecommendationFirstAudioContentUiModel> = emptyList()
|
||||||
@@ -19,11 +26,11 @@ class HomeFirstAudioAdapter : RecyclerView.Adapter<HomeFirstAudioAdapter.AudioVi
|
|||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AudioViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AudioViewHolder {
|
||||||
val view = LayoutInflater.from(parent.context).inflate(
|
val view = LayoutInflater.from(parent.context).inflate(
|
||||||
R.layout.view_audio_content_card,
|
R.layout.item_home_first_audio_content,
|
||||||
parent,
|
parent,
|
||||||
false
|
false
|
||||||
) as AudioContentCardView
|
)
|
||||||
view.layoutParams = recyclerItemLayoutParams(parent)
|
view.layoutParams = recyclerItemLayoutParams(parent, R.dimen.spacing_4)
|
||||||
return AudioViewHolder(view)
|
return AudioViewHolder(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,13 +41,61 @@ class HomeFirstAudioAdapter : RecyclerView.Adapter<HomeFirstAudioAdapter.AudioVi
|
|||||||
override fun getItemCount(): Int = items.size
|
override fun getItemCount(): Int = items.size
|
||||||
|
|
||||||
class AudioViewHolder(
|
class AudioViewHolder(
|
||||||
private val view: AudioContentCardView
|
private val view: View
|
||||||
) : RecyclerView.ViewHolder(view) {
|
) : RecyclerView.ViewHolder(view) {
|
||||||
|
private val thumbnail: ImageView = view.findViewById(R.id.iv_home_first_audio_thumbnail)
|
||||||
|
private val thumbnailContainer: FrameLayout = view.findViewById(R.id.fl_home_first_audio_thumbnail_container)
|
||||||
|
private val topTagContainer: LinearLayout = view.findViewById(R.id.ll_home_first_audio_tag_top)
|
||||||
|
private val firstTag: LinearLayout = view.findViewById(R.id.ll_home_first_audio_tag_first)
|
||||||
|
private val bottomTagContainer: LinearLayout = view.findViewById(R.id.ll_home_first_audio_tag_bottom)
|
||||||
|
private val pointTag: ImageView = view.findViewById(R.id.iv_home_first_audio_tag_point)
|
||||||
|
private val freeTag: TextView = view.findViewById(R.id.tv_home_first_audio_tag_free)
|
||||||
|
private val creatorProfile: ImageView = view.findViewById(R.id.iv_home_first_audio_creator_profile)
|
||||||
|
private val creatorNickname: TextView = view.findViewById(R.id.tv_home_first_audio_creator_nickname)
|
||||||
|
|
||||||
|
init {
|
||||||
|
thumbnailContainer.clipToOutline = true
|
||||||
|
thumbnailContainer.outlineProvider = object : ViewOutlineProvider() {
|
||||||
|
override fun getOutline(view: View, outline: Outline) {
|
||||||
|
outline.setRoundRect(0, 0, view.width, view.height, THUMBNAIL_RADIUS_DP.dpToPx())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun bind(item: HomeRecommendationFirstAudioContentUiModel) {
|
fun bind(item: HomeRecommendationFirstAudioContentUiModel) {
|
||||||
view.setSize(AudioContentCardSize.Medium)
|
bindImage(thumbnail, item.coverImage)
|
||||||
view.setContent(item.title, item.creatorNickname)
|
bindImage(creatorProfile, item.creatorProfileImage)
|
||||||
view.thumbnailView().loadUrl(item.coverImage)
|
creatorNickname.text = item.creatorNickname
|
||||||
view.setTags(item.tags)
|
bindTags(item.tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bindImage(
|
||||||
|
imageView: ImageView,
|
||||||
|
imageUrl: String?
|
||||||
|
) {
|
||||||
|
if (imageUrl == null) {
|
||||||
|
imageView.setImageDrawable(null)
|
||||||
|
} else {
|
||||||
|
imageView.loadUrl(imageUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bindTags(tags: Set<AudioContentTag>) {
|
||||||
|
firstTag.visibility = if (AudioContentTag.First in tags) View.VISIBLE else View.GONE
|
||||||
|
pointTag.visibility = if (AudioContentTag.Point in tags) View.VISIBLE else View.GONE
|
||||||
|
freeTag.visibility = if (AudioContentTag.Free in tags) View.VISIBLE else View.GONE
|
||||||
|
topTagContainer.visibility = if (firstTag.visibility == View.VISIBLE) View.VISIBLE else View.GONE
|
||||||
|
bottomTagContainer.visibility = if (
|
||||||
|
pointTag.visibility == View.VISIBLE || freeTag.visibility == View.VISIBLE
|
||||||
|
) {
|
||||||
|
View.VISIBLE
|
||||||
|
} else {
|
||||||
|
View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val THUMBNAIL_RADIUS_DP = 14f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,12 @@ import android.view.ViewGroup
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import kr.co.vividnext.sodalive.R
|
import kr.co.vividnext.sodalive.R
|
||||||
|
|
||||||
internal fun recyclerItemLayoutParams(parent: ViewGroup): RecyclerView.LayoutParams {
|
internal fun recyclerItemLayoutParams(
|
||||||
|
parent: ViewGroup,
|
||||||
|
marginEndResId: Int = R.dimen.spacing_12
|
||||||
|
): RecyclerView.LayoutParams {
|
||||||
return RecyclerView.LayoutParams(
|
return RecyclerView.LayoutParams(
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||||
).apply { marginEnd = parent.resources.getDimensionPixelSize(R.dimen.spacing_12) }
|
).apply { marginEnd = parent.resources.getDimensionPixelSize(marginEndResId) }
|
||||||
}
|
}
|
||||||
|
|||||||
120
app/src/main/res/layout/item_home_first_audio_content.xml
Normal file
120
app/src/main/res/layout/item_home_first_audio_content.xml
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<?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="185dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/fl_home_first_audio_thumbnail_container"
|
||||||
|
android:layout_width="185dp"
|
||||||
|
android:layout_height="185dp"
|
||||||
|
android:background="@drawable/bg_audio_content_card_thumbnail"
|
||||||
|
android:outlineProvider="background">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_home_first_audio_thumbnail"
|
||||||
|
android:layout_width="185dp"
|
||||||
|
android:layout_height="185dp"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
tools:src="@drawable/ic_launcher_background" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/ll_home_first_audio_tag_top"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="top|start"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/ll_home_first_audio_tag_first"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/spacing_24"
|
||||||
|
android:background="@drawable/bg_audio_content_tag_first"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="4dp"
|
||||||
|
tools:ignore="UselessParent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="17dp"
|
||||||
|
android:layout_height="17dp"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_content_tag_first_star" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="2dp"
|
||||||
|
android:fontFamily="@font/phosphate_solid"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:text="FIRST"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="16sp"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/ll_home_first_audio_tag_bottom"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom|start"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:ignore="UseCompoundDrawables"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_home_first_audio_tag_point"
|
||||||
|
android:layout_width="@dimen/spacing_24"
|
||||||
|
android:layout_height="@dimen/spacing_24"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_content_tag_point" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_home_first_audio_tag_free"
|
||||||
|
style="@style/Typography.Body4"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/spacing_24"
|
||||||
|
android:background="@drawable/bg_audio_content_tag_free"
|
||||||
|
android:gravity="center"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:text="@string/audio_content_tag_free"
|
||||||
|
android:textColor="@color/white" />
|
||||||
|
</LinearLayout>
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/spacing_8"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingHorizontal="6dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_home_first_audio_creator_profile"
|
||||||
|
android:layout_width="42dp"
|
||||||
|
android:layout_height="42dp"
|
||||||
|
android:background="@drawable/bg_round_corner_999_263238"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
tools:src="@drawable/ic_launcher_background" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_home_first_audio_creator_nickname"
|
||||||
|
style="@style/Typography.Body4"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/spacing_8"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
tools:text="크리에이터 이름" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
Reference in New Issue
Block a user