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

[feat/#138] 카드 뒷면 관심사 삭제/추가 디테일 수정 #139

Merged
merged 5 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -206,15 +206,6 @@ fun BackCardView(backCard: BackCard) {
factory = { context ->
BackCardView(context).apply {
getInstance(backCard)
submitInterestList( //todo - 더미
listOf(
Interest("모여서 각자 일하기"),
Interest("사이드 프로젝트"),
Interest("네트워킹")
)
)
setIsModifyDetail(isModifyDetail = true)
isModify = true
rotationY = 180f
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,30 @@ import androidx.recyclerview.widget.RecyclerView
import com.google.android.flexbox.FlexboxLayoutManager
import com.teumteum.teumteum.util.extension.dpToPx

class FlexboxItemDecoration(private val context: Context, private val horizontalSpaceDp: Int, private val verticalSpaceDp: Int) : RecyclerView.ItemDecoration() {
class FlexboxItemDecoration(private val context: Context, private val leftSpaceDp: Int, private val topSpaceDp: Int) : RecyclerView.ItemDecoration() {

private val horizontalSpacePx = horizontalSpaceDp.dpToPx(context)
private val verticalSpacePx = verticalSpaceDp.dpToPx(context)
private val leftSpacePx = leftSpaceDp.dpToPx(context)
private val topSpacePx = topSpaceDp.dpToPx(context)

override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
val layoutManager = parent.layoutManager as? FlexboxLayoutManager
val position = parent.getChildAdapterPosition(view)

layoutManager?.let {
val itemCount = parent.adapter?.itemCount ?: 0
val isLastRowItem = position >= itemCount - it.flexWrap
val isFirstInRow = position % it.flexWrap == 0

// 왼쪽에 아무것도 없는 첫 번째 아이템은 왼쪽 마진을 0으로 설정
if (isFirstInRow) {
outRect.left = 0
} else {
outRect.left = horizontalSpacePx
}

// 마지막 줄의 아이템은 아래 마진을 0으로 설정
if (isLastRowItem) {
outRect.bottom = 0
} else {
outRect.bottom = verticalSpacePx
outRect.left = leftSpacePx
}

// 상단 마진은 항상 동일하게 적용
outRect.top = verticalSpacePx
outRect.top = topSpacePx

// 오른쪽 마진은 항상 동일하게 적용
outRect.right = horizontalSpacePx
outRect.right = leftSpacePx
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import android.util.TypedValue
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.cardview.widget.CardView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
Expand Down Expand Up @@ -46,23 +47,43 @@ class BackCardView : CardView {
ivFloat.visibility = if (value) View.VISIBLE else View.INVISIBLE
}

var isModifyDetail: Boolean = false
set(value) {
field = value
ivEditGoalContent.visibility = if (value) View.VISIBLE else View.INVISIBLE
}

// isModifyDetail 값을 설정하고 어댑터에 UI 갱신을 알리는 함수
@SuppressLint("NotifyDataSetChanged")
fun setIsModifyDetail(isModifyDetail: Boolean) {
unam98 marked this conversation as resolved.
Show resolved Hide resolved
this.isModifyDetail = isModifyDetail //todo - 하나의 변수를 어댑터 안팎으로 2개씩 나눠 다루고 있는데 추후 하나로 통일
interestAdapter.isModifyDetail = isModifyDetail
// UI를 새로고침하도록 어댑터에 알림
interestAdapter.notifyDataSetChanged()
}

// 공개 속성으로 RecyclerView와 Adapter 제공
val interestAdapter = InterestAdapter()
val interestAdapter = InterestAdapter(context)
lateinit var rvInterests: RecyclerView
private set

fun submitInterestList(interests: List<Interest>) {
unam98 marked this conversation as resolved.
Show resolved Hide resolved
interestAdapter.submitList(interests.reversed()) //flexboxLayout에서 item 쌓이는 순서 reverse 지원을 안 해서 직접 item 순서를 뒤집어서 submitList
}
val currentList = interestAdapter.currentList.toMutableList()

if (!currentList.any { it.interest == "추가하기" }) {
currentList.add(Interest("추가하기"))
}

val availableSlots = 4 - currentList.size

if (interests.size > availableSlots) {
Toast.makeText(context, "최대 3개까지 선택할 수 있어요", Toast.LENGTH_SHORT).show()
} else {
val interestsToAdd = interests.take(availableSlots)
currentList.addAll(0, interestsToAdd)

interestAdapter.submitList(currentList.reversed())
}
}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
init(context, attrs)
}
Expand Down Expand Up @@ -206,8 +227,8 @@ class BackCardView : CardView {
marginBottom = 32,
marginStart = 32,
marginEnd = 32,
itemHorizontalSpaceDp = 8,
itemVerticalSpaceDp = 4,
itemLeftSpaceDp = 8,
itemTopSpaceDp = 8,
)
}

Expand Down Expand Up @@ -344,8 +365,8 @@ class BackCardView : CardView {
endToEndOf: Int? = null,
endToStartOf: Int? = null,
background: Int? = null,
itemHorizontalSpaceDp: Int,
itemVerticalSpaceDp: Int,
itemLeftSpaceDp: Int,
itemTopSpaceDp: Int,
) {
rvInterests = RecyclerView(context).apply {
this.id = id
Expand All @@ -362,8 +383,8 @@ class BackCardView : CardView {
addItemDecoration(
FlexboxItemDecoration(
context,
itemHorizontalSpaceDp,
itemVerticalSpaceDp
itemLeftSpaceDp,
itemTopSpaceDp
)
)
background?.let { setBackgroundResource(it) }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
package com.teumteum.teumteum.util.custom.view.adapter

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.teumteum.teumteum.R
import com.teumteum.teumteum.databinding.ItemInterestBinding
import com.teumteum.teumteum.util.custom.view.model.Interest
import timber.log.Timber

class InterestAdapter() : ListAdapter<Interest, InterestAdapter.ItemViewHolder>(
class InterestAdapter(val context: Context) : ListAdapter<Interest, InterestAdapter.ItemViewHolder>(
ItemListDiffCallback
) {
var isModifyDetail: Boolean = false // 외부에서 접근 가능하도록 isModifyDetail 속성 추가
var isModifyDetail: Boolean = false
var onAddItemClick: (() -> Unit)? = null

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
val binding = ItemInterestBinding.inflate(LayoutInflater.from(parent.context), parent, false)
// onCreateViewHolder 시점에 isModifyDetail 값을 ItemViewHolder에 전달
return ItemViewHolder(binding, isModifyDetail)
return ItemViewHolder(binding, isModifyDetail, onAddItemClick) { position ->
if (currentList.size > 2) {
removeItem(position)
} else {
Toast.makeText(context, "1개 이하는 삭제가 불가능 해요", Toast.LENGTH_SHORT).show()
}
}
}

override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
holder.bind(getItem(position))
holder.binding.root.setOnClickListener {
removeItem(position)
}
val item = getItem(position)
holder.bind(item)
}

private fun removeItem(position: Int) {
Expand All @@ -36,24 +42,38 @@ class InterestAdapter() : ListAdapter<Interest, InterestAdapter.ItemViewHolder>(
submitList(newList)
}

class ItemViewHolder(val binding: ItemInterestBinding, private val isModifyDetail: Boolean) :
RecyclerView.ViewHolder(binding.root) {
class ItemViewHolder(
private val binding: ItemInterestBinding,
private val isModifyDetail: Boolean,
private val onAddItemClick: (() -> Unit)?,
private val onRemoveItem: (position: Int) -> Unit
) : RecyclerView.ViewHolder(binding.root) {

fun bind(item: Interest) {
binding.tvInterest.text = itemView.context.getString(R.string.item_interest, item.interest)
// 생성자를 통해 전달받은 isModifyDetail 값을 사용
binding.ivDelete.visibility = if (isModifyDetail) View.VISIBLE else View.GONE
with(binding){
if (item.interest == "추가하기") {
tvInterest.text = item.interest
tvInterest.setTextColor(ContextCompat.getColor(itemView.context, com.teumteum.base.R.color.text_button_primary_default))
clInterest.setBackgroundResource(R.drawable.shape_rect4_color_outline_level01_active)
ivDelete.setImageDrawable(ContextCompat.getDrawable(itemView.context,R.drawable.ic_plus_fill))
root.setOnClickListener { onAddItemClick?.invoke() }
} else {
tvInterest.text = itemView.context.getString(R.string.item_interest, item.interest)
clInterest.setBackgroundResource(R.drawable.shape_rect4_background)
root.setOnClickListener(null)
ivDelete.setOnClickListener { onRemoveItem(absoluteAdapterPosition) }

}
ivDelete.visibility = if (isModifyDetail) View.VISIBLE else View.GONE
}
}
}

object ItemListDiffCallback : DiffUtil.ItemCallback<Interest>() {
override fun areItemsTheSame(oldItem: Interest, newItem: Interest): Boolean {
return oldItem == newItem
}
override fun areItemsTheSame(oldItem: Interest, newItem: Interest): Boolean =
oldItem == newItem

override fun areContentsTheSame(
oldItem: Interest, newItem: Interest
): Boolean {
return oldItem.interest == newItem.interest
}
override fun areContentsTheSame(oldItem: Interest, newItem: Interest): Boolean =
oldItem.interest == newItem.interest
}
}
2 changes: 1 addition & 1 deletion app/src/main/res/drawable-night/ic_plus_fill.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
android:viewportHeight="24">
<path
android:pathData="M5.636,18.364C9.151,21.879 14.849,21.879 18.364,18.364C21.879,14.849 21.879,9.151 18.364,5.636C14.849,2.121 9.151,2.121 5.636,5.636C2.121,9.151 2.121,14.849 5.636,18.364ZM11,16.243V13H7.757V11H11L11,7.757H13L13,11H16.243V13H13V16.243H11Z"
android:fillColor="#FFFFFF"
android:fillColor="#C9C9C9"
android:fillType="evenOdd"/>
</vector>
2 changes: 1 addition & 1 deletion app/src/main/res/drawable/ic_plus_fill.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
android:viewportHeight="24">
<path
android:pathData="M5.636,18.364C9.151,21.879 14.849,21.879 18.364,18.364C21.879,14.849 21.879,9.151 18.364,5.636C14.849,2.121 9.151,2.121 5.636,5.636C2.121,9.151 2.121,14.849 5.636,18.364ZM11,16.243V13H7.757V11H11L11,7.757H13L13,11H16.243V13H13V16.243H11Z"
android:fillColor="#C9C9C9"
android:fillColor="#FFFFFF"
android:fillType="evenOdd"/>
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">

<solid android:color="@color/outline_level01_active" />
<corners android:radius="4dp" />
</shape>
18 changes: 11 additions & 7 deletions app/src/main/res/layout/item_interest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@
<data></data>

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_interest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rect4_background"
android:padding="8dp"
android:theme="@style/Theme.TeumTeum">

<TextView
android:id="@+id/tv_interest"
style="@style/ta.caption.2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginVertical="8dp"
android:layout_marginStart="8dp"
android:textColor="@color/text_caption_secondary_default"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/iv_delete"
Expand All @@ -26,15 +28,17 @@

<ImageView
android:id="@+id/iv_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginVertical="6dp"
android:layout_marginStart="4dp"
android:layout_marginEnd="8dp"
android:src="@drawable/ic__system_fill"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/tv_interest"
app:layout_constraintEnd_toEndOf="@id/tv_interest"
app:layout_constraintBottom_toBottomOf="@id/cl_interest"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="@id/cl_interest"
app:layout_constraintStart_toEndOf="@id/tv_interest"
app:layout_constraintTop_toTopOf="@id/tv_interest" />
app:layout_constraintTop_toTopOf="@id/cl_interest" />

</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Loading