Skip to content

Commit

Permalink
Implement a Click Listener with RecyclerView and DataBinding
Browse files Browse the repository at this point in the history
  • Loading branch information
ChaMinZi committed Jun 7, 2021
1 parent 85b2b5a commit 7fcd74e
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import com.example.android.trackmysleepquality.convertDurationToFormatted
import com.example.android.trackmysleepquality.convertNumericQualityToString
import com.example.android.trackmysleepquality.database.SleepNight
import com.example.android.trackmysleepquality.databinding.ListItemSleepNightBinding
import com.example.android.trackmysleepquality.generated.callback.OnClickListener

class SleepNightAdapter : ListAdapter<SleepNight,
class SleepNightAdapter(private val clickListener:SleepNightListener) : ListAdapter<SleepNight,
SleepNightAdapter.ViewHolder>(SleepNightDiffCallback()) {

// ViewHolder 만 변경해서 다른 로직으로 바꿀 수 있게 캡슐화 됨
Expand All @@ -20,8 +21,7 @@ class SleepNightAdapter : ListAdapter<SleepNight,
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = getItem(position)
holder.bind(item)
holder.bind(getItem(position)!!, clickListener)
}

/**
Expand All @@ -30,8 +30,9 @@ class SleepNightAdapter : ListAdapter<SleepNight,
class ViewHolder private constructor(val binding: ListItemSleepNightBinding) : RecyclerView.ViewHolder(binding.root) {

// RecyclerView는 여러 타입의 ViewHolder를 지원할 수 있기 때문에 캡슐화
fun bind(item: SleepNight) {
fun bind(item: SleepNight, clickListener: SleepNightListener) {
binding.sleep = item
binding.clickListener = clickListener
binding.executePendingBindings()
}

Expand All @@ -58,4 +59,15 @@ class SleepNightDiffCallback : DiffUtil.ItemCallback<SleepNight>() {
override fun areContentsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
return oldItem == newItem
}
}

/**
* click 을 감지하고 클릭과 관련되어 처리해야 데이터를 fragment 에 전달합니다.
* click event 가 발생할 때마다 이를 fragment 에 알리는 아래의 Callback method 는 ViewHolder 가 가지고 있을 것입니다.
*
* nightId만 있어도 Database 에서 원하는 데이터에 접근할 수 있기 때문에
* SleepNight 객체 참조를 가지고 있을 필요는 없습니다. 따라서 sleep night id 만 파라미터로 넘겨줍니다.
**/
class SleepNightListener(val clickListener: (sleepId: Long) -> Unit) {
fun onClick(night: SleepNight) = clickListener(night.nightId)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
Expand Down Expand Up @@ -50,7 +51,9 @@ class SleepTrackerFragment : Fragment() {
binding.sleepList.layoutManager = manager

// recyclerView setting
val adapter = SleepNightAdapter()
val adapter = SleepNightAdapter(SleepNightListener { nightId ->
Toast.makeText(context, "$nightId", Toast.LENGTH_LONG).show()
})
binding.sleepList.adapter = adapter

sleepTrackerViewModel.nights.observe(viewLifecycleOwner, Observer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@
<variable
name="sleep"
type="com.example.android.trackmysleepquality.database.SleepNight" />

<variable
name="clickListener"
type="com.example.android.trackmysleepquality.sleeptracker.SleepNightListener" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:onClick="@{() -> clickListener.onClick(sleep)}">

<ImageView
android:id="@+id/quality_image"
Expand Down

0 comments on commit 7fcd74e

Please sign in to comment.