참고로 Adapter를 만들 때 기본 뼈대를 제공해주면 보일러 플레이드 코드없이 손쉽게 Adapter를 처리할 수 있을 것 같습니다.
abstract class GenericAdapter<T: ListItem>(initialItem: List<T> = emptyList(), diffCallback: DiffUtil.ItemCallback<T> = BasicItemCallback<T>()) :
ListAdapter<T, GenericViewHolder<T>>(diffCallback) {
init {
this.submitList(initialItem)
}
override fun getItemViewType(position: Int): Int = getItem(position).layoutId
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GenericViewHolder<T> {
val itemView = LayoutInflater.from(parent.context)
.inflate(viewType, parent, false)
return createViewHolder(itemView)
}
abstract fun createViewHolder(itemView: View): GenericViewHolder<T>
override fun onBindViewHolder(holder: GenericViewHolder<T>, position: Int) {
holder.bind(getItem(position))
}
}
interface ListItem {
val layoutId: Int
}
이렇게 베이스 클래스를 만들고
class BasicItemCallback<T> : DiffUtil.ItemCallback<T>() {
override fun areItemsTheSame(oldItem: T, newItem: T): Boolean {
return oldItem == newItem
}
override fun areContentsTheSame(oldItem: T, newItem: T): Boolean {
return oldItem == newItem
}
}
class TaskHeaderAdapter(item: TaskListItem.Header) :
GenericAdapter<TaskListItem.Header>(initialItem = listOf(item)) {
override fun createViewHolder(itemView: View): GenericViewHolder<TaskListItem.Header> {
return TaskHeaderViewHolder(itemView)
}
}
class TaskHeaderViewHolder(
itemView: View
) : GenericViewHolder<TaskListItem.Header>(itemView) {
private val binding by lazy { ItemTaskHeaderBinding.bind(itemView) }
override fun bind(item: TaskListItem.Header) {
binding.apply {
startDateTxt.text = item.startTime
}
}
}
class TaskItemAdapter(tasks: List<TaskListItem.Item> = emptyList()) :
GenericAdapter<TaskListItem.Item>(initialItem = tasks) {
override fun createViewHolder(itemView: View): GenericViewHolder<TaskListItem.Item> {
return TaskItemViewHolder(itemView)
}
}
class TaskItemViewHolder(
itemView: View
) : GenericViewHolder<TaskListItem.Item>(itemView) {
private val binding by lazy { ItemTaskBinding.bind(itemView) }
override fun bind(item: TaskListItem.Item) {
val task = item.task
binding.apply {
val alarmResId = if (task.hasAlarm) R.drawable.ic_alarm_on else R.drawable.ic_alarm_off
alarmImg.setImageResource(alarmResId)
contentTxt.text = if (task.isDone) task.content.strikeThrough() else task.content
endDateTxt.text =
if (task.end_time.isNotBlank()) "~ ".plus(task.end_time.takeLast(5)) else ""
}
}
}
위와 같은 식으로 처리하면 코드량이 많이 줄어들 것 같습니다. 좀더 리팩토링하면 createViewHolder같은 부분도 더 간결하게 처리할 수 있을 듯합니다. 아무튼 보완하면 위의 코드보다 더 좋은 코드를 만들 수 있을 겁니다.