Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AN/USER] feat: 축제 목록 디자인 수정(#698) #701

Merged
merged 7 commits into from
Feb 10, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ class FestivalListPopularViewHolder(val binding: ItemFestivalListPopularBinding)
PopularFestivalViewPagerAdapter(
foregroundViewPager = binding.vpPopularFestivalForeground,
backgroundViewPager = binding.vpPopularFestivalBackground,
)
) { item ->
binding.item = item
binding.tvPopularFestivalArtistsName.text =
item.artists.joinToString(ARTIST_NAME_JOIN_SEPARATOR) { it.name }
}

init {
TabLayoutMediator(
Expand All @@ -27,6 +31,8 @@ class FestivalListPopularViewHolder(val binding: ItemFestivalListPopularBinding)
}

companion object {
private const val ARTIST_NAME_JOIN_SEPARATOR = ", "

fun of(parent: ViewGroup): FestivalListPopularViewHolder {
val binding = ItemFestivalListPopularBinding.inflate(
LayoutInflater.from(parent.context),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package com.festago.festago.presentation.ui.home.festivallist.popularfestival

import android.content.res.Resources
import android.view.View
import androidx.viewpager2.widget.ViewPager2
import com.festago.festago.presentation.ui.home.festivallist.popularfestival.background.PopularFestivalBackgroundAdapter
import com.festago.festago.presentation.ui.home.festivallist.popularfestival.foreground.PopularFestivalForegroundAdapter
import com.festago.festago.presentation.ui.home.festivallist.uistate.FestivalItemUiState
import kotlin.math.abs

class PopularFestivalViewPagerAdapter(
foregroundViewPager: ViewPager2,
backgroundViewPager: ViewPager2,
private val onPopularFestivalSelected: (FestivalItemUiState) -> Unit,
) {

private val popularFestivals = mutableListOf<FestivalItemUiState>()
private val foregroundAdapter: PopularFestivalForegroundAdapter =
PopularFestivalForegroundAdapter()
private val backgroundAdapter: PopularFestivalBackgroundAdapter =
Expand All @@ -32,34 +36,67 @@ class PopularFestivalViewPagerAdapter(
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
target.setCurrentItem(position, false)
onPopularFestivalSelected(popularFestivals[position])
}
}
viewpager.registerOnPageChangeCallback(onPageChangeCallback)
}

private fun narrowSpaceViewPager(viewPager: ViewPager2) {
viewPager.setPageTransformer { page, position ->
val offset = position * -(2 * dpToPx(OFFSET_BETWEEN_PAGES))
page.translationX = offset
translateOffsetBetweenPages(position, page)
reduceUnselectedPagesScale(page, position)
}
}

private fun translateOffsetBetweenPages(position: Float, page: View) {
val screenWidth = Resources.getSystem().configuration.screenWidthDp
val offsetBetweenPages = screenWidth - IMAGE_SIZE - INTERVAL_IMAGE
val reducedDifference = IMAGE_SIZE - (IMAGE_SIZE * RATE_SELECT_BY_UNSELECT)
val offset = position * -dpToPx(offsetBetweenPages + reducedDifference * 0.5f)
page.translationX = offset
}

private fun dpToPx(dp: Float): Int {
val density = Resources.getSystem().displayMetrics.density
return (dp * density).toInt()
}

private fun reduceUnselectedPagesScale(page: View, position: Float) {
page.movePivotTo(x = page.pivotX, y = MIDDLE_IMAGE_PIVOT)
if (position <= ALREADY_LOAD_POSITION_CONDITION) {
page.reduceScaleBy(position = position, rate = RATE_SELECT_BY_UNSELECT)
}
}

private fun View.movePivotTo(x: Float, y: Float) {
pivotX = x
pivotY = y
}

private fun View.reduceScaleBy(position: Float, rate: Float) {
val scaleFactor = rate.coerceAtLeast(1 - abs(position))
scaleY = scaleFactor
scaleX = scaleFactor
}

private fun setOffscreenPagesLimit(viewPager: ViewPager2, limit: Int) {
viewPager.offscreenPageLimit = limit
}

fun submitList(popularFestivals: List<FestivalItemUiState>) {
foregroundAdapter.submitList(popularFestivals)
backgroundAdapter.submitList(popularFestivals)
fun submitList(festivals: List<FestivalItemUiState>) {
popularFestivals.clear()
popularFestivals.addAll(festivals)
foregroundAdapter.submitList(festivals)
backgroundAdapter.submitList(festivals)
}

companion object {
private const val PAGE_LIMIT = 3
private const val OFFSET_BETWEEN_PAGES = 63.0f
private const val ALREADY_LOAD_POSITION_CONDITION = 2
private const val RATE_SELECT_BY_UNSELECT = 0.81f
private const val PAGE_LIMIT = 4
private const val IMAGE_SIZE = 220.0f
private const val INTERVAL_IMAGE = 24.0f
private const val MIDDLE_IMAGE_PIVOT = 360.0f
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.festago.festago.presentation.ui.home.festivallist.popularfestival.foreground

import android.content.res.Resources
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
Expand All @@ -14,26 +13,9 @@ class PopularFestivalForegroundViewHolder(

fun bind(item: FestivalItemUiState) {
binding.item = item
binding.ivPopularFestivalImage.outlineProvider
binding.tvPopularFestivalArtistsName.text =
item.artists.joinToString(ARTIST_NAME_JOIN_SEPARATOR) { it.name }
setImageSizeFlexibleToScreenWidth()
}

private fun setImageSizeFlexibleToScreenWidth() {
val imageSize = Resources.getSystem().configuration.screenWidthDp - MINUS_TO_IMAGE_SIZE
val density = Resources.getSystem().displayMetrics.density

binding.ivPopularFestivalImage.layoutParams.apply {
this.width = (imageSize * density + ROUNDUP_CONDITION).toInt()
this.height = (imageSize * density + ROUNDUP_CONDITION).toInt()
}
}

companion object {
private const val MINUS_TO_IMAGE_SIZE = 160
private const val ROUNDUP_CONDITION = 0.5f
private const val ARTIST_NAME_JOIN_SEPARATOR = ", "

fun of(parent: ViewGroup): PopularFestivalForegroundViewHolder {
val binding = ItemPopularFestivalForegroundBinding.inflate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<shape
android:innerRadius="0dp"
android:shape="ring"
android:thickness="4dp"
android:thickness="2dp"
android:useLevel="false">
<solid android:color="@color/background_gray_01" />
</shape>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<shape
android:innerRadius="0dp"
android:shape="ring"
android:thickness="4dp"
android:thickness="2dp"
android:useLevel="false">
<solid android:color="@color/contents_gray_07" />
</shape>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<data>

<import type="java.time.format.DateTimeFormatter" />

<variable
name="item"
type="com.festago.festago.presentation.ui.home.festivallist.uistate.FestivalItemUiState" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
Expand All @@ -25,23 +35,73 @@
android:textColor="@color/background_gray_01"
app:layout_constraintTop_toTopOf="@id/vpPopularFestivalBackground" />

<TextView
android:id="@+id/tvPopularFestivalName"
style="@style/H3Bold18Lh20"
android:layout_width="220dp"
android:layout_height="wrap_content"
android:layout_marginTop="248dp"
android:ellipsize="end"
android:gravity="center"
android:lineSpacingExtra="0dp"
android:maxLines="2"
android:text="@{item.schoolUiState.name+'\n'+ item.name }"
android:textColor="@color/background_gray_01"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/vpPopularFestivalForeground"
tools:text="대학교 \n 축제 이름" />

<TextView
android:id="@+id/tvFestivalSchedule"
style="@style/B2Medium14Lh20"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:text="@{@string/festival_list_tv_date_range_format(item.startDate.format(DateTimeFormatter.ofPattern(@string/festival_list_tv_date_format)),item.endDate.format(DateTimeFormatter.ofPattern(@string/festival_list_tv_date_format)))}"
android:textColor="@color/background_gray_01"
app:layout_constraintEnd_toEndOf="@+id/tvPopularFestivalName"
app:layout_constraintStart_toStartOf="@+id/tvPopularFestivalName"
app:layout_constraintTop_toBottomOf="@id/tvPopularFestivalName"
tools:text="2023.07.03 - 2023.07.09" />

<TextView
android:id="@+id/tvPopularFestivalArtistsName"
style="@style/B2Medium14Lh20"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center"
android:lineSpacingExtra="0dp"
android:lines="2"
android:textColor="@color/background_gray_01"
app:layout_constraintEnd_toEndOf="@+id/tvFestivalSchedule"
app:layout_constraintStart_toStartOf="@+id/tvFestivalSchedule"
app:layout_constraintTop_toBottomOf="@id/tvFestivalSchedule"
tools:text="르세라핌, 아이브, 뉴진스, \n다이나믹 듀오" />

<androidx.viewpager2.widget.ViewPager2
android:id="@+id/vpPopularFestivalForeground"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="12dp"
app:layout_constraintBottom_toBottomOf="@id/tlDotIndicator"
app:layout_constraintTop_toBottomOf="@id/tvPopularFestivalTitle" />

<com.google.android.material.tabs.TabLayout
android:id="@+id/tlDotIndicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
app:layout_constraintTop_toBottomOf="@id/vpPopularFestivalForeground"
app:layout_constraintTop_toBottomOf="@id/tvPopularFestivalArtistsName"
app:tabBackground="@drawable/selector_tab_page"
app:tabGravity="center"
app:tabIndicatorHeight="0dp"
app:tabPaddingEnd="8dp"
app:tabPaddingStart="8dp" />

<androidx.viewpager2.widget.ViewPager2
android:id="@+id/vpPopularFestivalForeground"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/tvPopularFestivalTitle" />

</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
android:id="@+id/tlFestivalListTab"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginHorizontal="16dp"
android:background="@android:color/transparent"
app:tabGravity="fill"
app:tabIndicatorColor="@color/contents_gray_07"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,70 +20,19 @@
<ImageView
android:id="@+id/ivPopularFestivalImage"
imageUrl="@{item.imageUrl}"
android:layout_width="200dp"
android:layout_height="200dp"
android:outlineProvider="bounds"
android:layout_marginTop="24dp"
android:layout_width="220dp"
android:layout_height="220dp"
android:layout_marginTop="12dp"
android:elevation="12dp"
android:importantForAccessibility="no"
android:outlineProvider="bounds"
android:scaleType="centerCrop"
android:elevation="10dp"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintDimensionRatio="1:1"
tools:src="@drawable/ic_launcher_background" />


<TextView
android:id="@+id/tvPopularFestivalName"
style="@style/H3Bold18Lh20"
android:textColor="@color/background_gray_01"
android:layout_width="0dp"
android:layout_marginTop="16dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center"
android:maxLines="2"
android:lineSpacingExtra="0dp"
android:text="@{item.schoolUiState.name+'\n'+ item.name }"
app:layout_constraintTop_toBottomOf="@id/ivPopularFestivalImage"
app:layout_constraintEnd_toEndOf="@+id/ivPopularFestivalImage"
app:layout_constraintStart_toStartOf="@+id/ivPopularFestivalImage"
tools:text="대학교 \n 축제 이름" />


<TextView
android:id="@+id/tvFestivalSchedule"
style="@style/B2Medium14Lh20"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="@color/background_gray_01"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:layout_marginTop="8dp"
android:text="@{@string/festival_list_tv_date_range_format(item.startDate.format(DateTimeFormatter.ofPattern(@string/festival_list_tv_date_format)),item.endDate.format(DateTimeFormatter.ofPattern(@string/festival_list_tv_date_format)))}"
app:layout_constraintTop_toBottomOf="@id/tvPopularFestivalName"
app:layout_constraintEnd_toEndOf="@+id/ivPopularFestivalImage"
tools:text="2023.07.03 - 2023.07.09"
app:layout_constraintStart_toStartOf="@+id/ivPopularFestivalImage" />

<TextView
android:id="@+id/tvPopularFestivalArtistsName"
style="@style/B2Medium14Lh20"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="@color/background_gray_01"
android:ellipsize="end"
android:gravity="center"
android:lineSpacingExtra="0dp"
android:lines="2"
app:layout_constraintTop_toBottomOf="@id/tvFestivalSchedule"
app:layout_constraintEnd_toEndOf="@+id/ivPopularFestivalImage"
app:layout_constraintStart_toStartOf="@+id/ivPopularFestivalImage"
tools:text="르세라핌, 아이브, 뉴진스, \n다이나믹 듀오" />


</androidx.constraintlayout.widget.ConstraintLayout>

</layout>
</layout>
Loading