Skip to content

Commit

Permalink
[AN] feat: 강아지 선택 기능 구현 (#90)
Browse files Browse the repository at this point in the history
  • Loading branch information
jinuemong authored Jul 18, 2024
1 parent c1c26e6 commit ffcb405
Show file tree
Hide file tree
Showing 10 changed files with 330 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.woowacourse.friendogly.presentation.ui.group.select

interface DogSelectActionHandler {
fun choiceDog(dogSelectUiModel: DogSelectUiModel)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.woowacourse.friendogly.presentation.ui.group.select

import android.graphics.Color
import android.view.View
import androidx.databinding.BindingAdapter

@BindingAdapter("bindingSelectBorder")
fun dogSelect(
view: View,
dogSelectUiModel: DogSelectUiModel,
) {
view.setBackgroundColor(
if (dogSelectUiModel.isSelected) {
Color.GREEN
} else {
Color.GRAY
},
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.woowacourse.friendogly.presentation.ui.group.select

import android.annotation.SuppressLint
import android.view.View
import androidx.fragment.app.viewModels
import androidx.viewpager2.widget.CompositePageTransformer
import androidx.viewpager2.widget.MarginPageTransformer
import com.woowacourse.friendogly.R
import com.woowacourse.friendogly.databinding.FragmentDogSelectBinding
import com.woowacourse.friendogly.presentation.base.BaseFragment
import com.woowacourse.friendogly.presentation.ui.group.select.adapter.DogSelectAdapter
import kotlin.math.abs

class DogSelectFragment : BaseFragment<FragmentDogSelectBinding>(R.layout.fragment_dog_select) {
private val viewModel: DogSelectViewModel by viewModels()
private val adapter: DogSelectAdapter by lazy {
DogSelectAdapter(viewModel as DogSelectActionHandler)
}

override fun initViewCreated() {
initDataBinding()
initObserver()
initViewPager()
}

private fun initDataBinding() {
binding.lifecycleOwner = viewLifecycleOwner
binding.vm = viewModel
}

@SuppressLint("NotifyDataSetChanged")
private fun initObserver() {
viewModel.dogs.observe(viewLifecycleOwner) { dogs ->
adapter.submitList(dogs)
}

viewModel.dogSelectEvent.observe(viewLifecycleOwner) {
adapter.notifyItemChanged(binding.vpGroupSelectDogList.currentItem)
}
}

private fun initViewPager() {
val viewPager = binding.vpGroupSelectDogList
viewPager.offscreenPageLimit = 3
viewPager.getChildAt(0).overScrollMode = View.OVER_SCROLL_NEVER
viewPager.adapter = adapter
initNearViewSize()
}

private fun initNearViewSize() {
val transform = CompositePageTransformer()
transform.addTransformer(MarginPageTransformer(8))
transform.addTransformer { view: View, fl: Float ->
val v = 1 - abs(fl)
view.scaleY = 0.8f + v * 0.2f
}
binding.vpGroupSelectDogList.setPageTransformer(transform)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.woowacourse.friendogly.presentation.ui.group.select

data class DogSelectUiModel(
val id: Long,
val name: String,
val profileImage: String,
) {
var isSelected = false
private set

fun selectDog() {
isSelected = true
}

fun unSelectDog() {
isSelected = false
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.woowacourse.friendogly.presentation.ui.group.select

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.woowacourse.friendogly.presentation.base.BaseViewModel
import com.woowacourse.friendogly.presentation.base.Event
import com.woowacourse.friendogly.presentation.base.emit
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

class DogSelectViewModel : BaseViewModel(), DogSelectActionHandler {
private val _dogs: MutableLiveData<List<DogSelectUiModel>> = MutableLiveData()
val dogs: LiveData<List<DogSelectUiModel>> get() = _dogs

private val selectedDogs: MutableList<DogSelectUiModel> = mutableListOf()

private val _dogSelectEvent: MutableLiveData<Event<Unit>> = MutableLiveData()
val dogSelectEvent: LiveData<Event<Unit>> get() = _dogSelectEvent

init {
loadMyDogs()
}

// TODO: romove sample
private fun loadMyDogs() =
viewModelScope.launch {
delay(1000)
_dogs.value =
listOf(
DogSelectUiModel(
id = 0L,
profileImage = "",
name = "강아지 1",
),
DogSelectUiModel(
id = 0L,
profileImage = "",
name = "강아지 2",
),
DogSelectUiModel(
id = 0L,
profileImage = "",
name = "강아지 3",
),
DogSelectUiModel(
id = 0L,
profileImage = "",
name = "강아지 4",
),
DogSelectUiModel(
id = 0L,
profileImage = "",
name = "강아지 5",
),
)
}

override fun choiceDog(dogSelectUiModel: DogSelectUiModel) {
if (selectedDogs.contains(dogSelectUiModel)) {
dogSelectUiModel.unSelectDog()
selectedDogs.remove(dogSelectUiModel)
} else {
dogSelectUiModel.selectDog()
selectedDogs.add(dogSelectUiModel)
}
_dogSelectEvent.emit()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.woowacourse.friendogly.presentation.ui.group.select.adapter

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import com.woowacourse.friendogly.databinding.ItemDogSelectProfileBinding
import com.woowacourse.friendogly.presentation.ui.group.select.DogSelectActionHandler
import com.woowacourse.friendogly.presentation.ui.group.select.DogSelectUiModel

class DogSelectAdapter(
private val actionHandler: DogSelectActionHandler,
) : ListAdapter<DogSelectUiModel, DogSelectViewHolder>(DogSelectDiffCallback()) {
class DogSelectDiffCallback : DiffUtil.ItemCallback<DogSelectUiModel>() {
override fun areItemsTheSame(
oldItem: DogSelectUiModel,
newItem: DogSelectUiModel,
): Boolean {
return oldItem.id == newItem.id
}

override fun areContentsTheSame(
oldItem: DogSelectUiModel,
newItem: DogSelectUiModel,
): Boolean {
return oldItem == newItem
}
}

override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int,
): DogSelectViewHolder {
val view = ItemDogSelectProfileBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return DogSelectViewHolder(view, actionHandler)
}

override fun onBindViewHolder(
holder: DogSelectViewHolder,
position: Int,
) {
val item = getItem(position)
holder.bind(item)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.woowacourse.friendogly.presentation.ui.group.select.adapter

import androidx.recyclerview.widget.RecyclerView
import com.woowacourse.friendogly.databinding.ItemDogSelectProfileBinding
import com.woowacourse.friendogly.presentation.ui.group.select.DogSelectActionHandler
import com.woowacourse.friendogly.presentation.ui.group.select.DogSelectUiModel

class DogSelectViewHolder(
private val binding: ItemDogSelectProfileBinding,
private val actionHandler: DogSelectActionHandler,
) : RecyclerView.ViewHolder(binding.root) {
fun bind(dogSelectUiModel: DogSelectUiModel) {
binding.dogUiModel = dogSelectUiModel
binding.dogSelectActionHandler = actionHandler
}
}
60 changes: 60 additions & 0 deletions android/app/src/main/res/layout/fragment_dog_select.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>
<variable
name="vm"
type="com.woowacourse.friendogly.presentation.ui.group.select.DogSelectViewModel" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".presentation.ui.group.select.DogSelectFragment">
<View
android:id="@+id/view_group_select_top_bar"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="match_parent"
android:layout_height="56dp"/>
<ImageView
android:layout_marginStart="12dp"
android:src="@drawable/ic_arrow_left"
app:layout_constraintTop_toTopOf="@id/view_group_select_top_bar"
app:layout_constraintBottom_toBottomOf="@id/view_group_select_top_bar"
app:layout_constraintStart_toStartOf="@id/view_group_select_top_bar"
android:id="@+id/iv_group_select_back_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
style="@style/Theme.AppCompat.TextView.SemiBold.Black.Size16"
android:text="@string/group_select_dog_subject"
app:layout_constraintTop_toTopOf="@id/view_group_select_top_bar"
app:layout_constraintBottom_toBottomOf="@id/view_group_select_top_bar"
app:layout_constraintStart_toStartOf="@id/view_group_select_top_bar"
app:layout_constraintEnd_toEndOf="@id/view_group_select_top_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

<androidx.viewpager2.widget.ViewPager2
android:paddingHorizontal="30dp"
android:id="@+id/vp_group_select_dog_list"
app:layout_constraintTop_toBottomOf="@id/view_group_select_top_bar"
app:layout_constraintBottom_toTopOf="@id/btn_group_select_commit"
android:layout_width="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:layout_height="400dp"/>

<Button
android:id="@+id/btn_group_select_commit"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_marginHorizontal="10dp"
android:background="@drawable/rect_white_fill_radius10"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/vp_group_select_dog_list"
android:text="@string/group_select_commit" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
37 changes: 37 additions & 0 deletions android/app/src/main/res/layout/item_dog_select_profile.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?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:tools="http://schemas.android.com/tools">

<data>
<variable
name="dogSelectActionHandler"
type="com.woowacourse.friendogly.presentation.ui.group.select.DogSelectActionHandler" />

<variable
name="dogUiModel"
type="com.woowacourse.friendogly.presentation.ui.group.select.DogSelectUiModel" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
app:bindingSelectBorder="@{dogUiModel}"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="@{()->dogSelectActionHandler.choiceDog(dogUiModel)}">

<ImageView
android:background="@color/white"
android:layout_margin="5dp"
android:layout_width="match_parent"
android:layout_height="match_parent" />

<TextView
style="@style/Theme.AppCompat.TextView.Regular.Black.Size14"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
tools:text="땡이 준비 갈 완료" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
2 changes: 2 additions & 0 deletions android/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
<!--멍개-->
<string name="group_user_list_subject">참여 견주</string>
<string name="group_dog_list_subject">댕댕이들</string>
<string name="group_select_dog_subject">내 댕댕이 선택</string>
<string name="group_select_commit">선택완료</string>

<!--채팅-->
<string name="chat_list_title">채팅</string>
Expand Down

0 comments on commit ffcb405

Please sign in to comment.