일일 회고
숙련 프로젝트가 마무리되었다. 다른 조의 발표도 보았고, 발표들을 통해 우리 조의 잘한 점과 아쉬운 점을 생각해 볼 수 있었다.
프로젝트는 끝이 났지만 간간히 코드를 보면서 복습을 하는 시간을 가지는 것도 좋을 것 같다.
내일부터는 심화과정의 시작이다. 난이도가 확! 올라간다고 하였으니 마음 가다듬고 열심히 임해야 할 것 같다!.
오늘의 키워드
- 프로젝트 피드백
- 선발대 과제
- 안드로이드 12 이후 스플래시 스크린 대응
프로젝트 피드백
동준 튜터님 - 시연영상이 좀 짧다. 조금만 길었으면 좋겠다. 영상이 짧아서 이해하기가 약간 아쉬웠다. 기능적인 면은 잘 구현된 것 같다.
성휘 튜터님 - 탭 인디케이터 색이 아쉽다 색이 확 구분되지 않아 어느 탭이 눌렸는 지 알기가 어렵다. 하이픈 붙이는 것 좋았다. 인텐트 연결 좋았다. 어려웠던 점 잘 구현했다.
버튼 눌릴때 효과가 부족하여 어떠한 행동을 하는지 몰라 약간 아쉬웠다,
선발대 과제
ListAdapter - DiffUtil 적용
RecyclerView.Adapter에서 ListAdapter로 전환을 하였다.
package com.jess.camp.todo.home
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.jess.camp.databinding.TodoItemBinding
import com.jess.camp.todo.home.listener.TodoItemClickListener
class TodoListViewAdapter :
ListAdapter<TodoModel, TodoListViewAdapter.TodoViewHolder>(TodoModel.DIFF_CALLBACK) {
private lateinit var itemClickListener: TodoItemClickListener
fun setOnClickListener(listener: TodoItemClickListener) {
itemClickListener = listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TodoViewHolder {
return TodoViewHolder(
TodoItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
)
}
override fun onBindViewHolder(holder: TodoViewHolder, position: Int) {
val item = currentList[position]
holder.bind(item)
}
inner class TodoViewHolder(private val binding: TodoItemBinding) :
RecyclerView.ViewHolder(binding.root) {
init {
binding.root.setOnClickListener {
itemClickListener.onItemClick(adapterPosition)
}
}
fun bind(item: TodoModel) = with(binding) {
title.text = item.title
description.text = item.description
switchBookmark.isChecked = item.isChecked
switchBookmark.setOnCheckedChangeListener { _, isChecked ->
currentList.find { it.id == item.id }?.isChecked = isChecked
}
}
}
}
기존 RecylcerView.Adapter에서는 내부에서 리스트를 직접 관리해야 하지만, ListAdapter는 자체적으로 currentList라는 리스트로 관리를 할 수 있기 때문에, Adapter 클래스를 간결하게 작성할 수 있다.
DiffUtil
배경 - 보통 RecyclerView를 사용하다보면 notifyDataSetChanged() 메서드를 통해 RecyclerView를 갱신한다.
여기서 notifyDataSetChanged() 는 리스트를 싹 지우고 처음부터 다시 객체를 만들어 새로 렌더링을 하는 과정을 거친다.
이 과정에서 비용이 매우 크게 발생하여 성능에 악영향을 미칠 수 있다.
여기서 등장한 것이 DiffUtil이다.
DiffUtil 클래스는 이전 데이터 상태와 현재 데이터 간의 상태 차이를 계산하고, 업데이트해야 할 최소한의 데이터에 대해서만 갱신하게 된다. 업데이트 횟수를 최소한으로 가져가는 것이다.
DiffUtil은 원래 목록과 새로운 목록 간의 차이를 계산하는 방식으로 동작된다.
areItemsTheSame - 아이템의 특정 요소가 같은 지 판단함
areContentTheSame - 아이템 객체 자체가 같은 지 판단함
companion object {
val DIFF_CALLBACK: DiffUtil.ItemCallback<TodoModel> = object : DiffUtil.ItemCallback<TodoModel>() {
override fun areItemsTheSame(oldItem: TodoModel, newItem: TodoModel): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: TodoModel, newItem: TodoModel): Boolean {
return oldItem == newItem
}
}
}
ViewModel 적용
class TodoViewModel: ViewModel() {
private val _list = MutableLiveData<List<TodoModel>>()
val list: LiveData<List<TodoModel>>
get() = _list
fun loadItems(items: List<TodoModel>) {
_list.value = items
}
}
viewModel.list.observe(viewLifecycleOwner) { list ->
listAdapter.submitList(list.toMutableList())
}
viewModel을 만들고, fragment에서 viewModel의 LiveData에 옵저버를 부착하여, 리스트가 바뀔 때마다, ListAdapter에 새로운 데이터를 부여하는 방식으로 변경하였다.
안드로이드 12 이후 splash screen
프로젝트 스플래시 화면을 구현하는데 기본 스플래시 화면이 있던 것을 시작으로 하였다.
찾아보았더니 android 12 SDK 32 이후로는 기본 스플래시 화면이 강제되어, 그것을 커스텀해서 사용해야 했던 것이다.
기존 스플래시 화면 구현을 Android 12 이상으로 이전 | Android 개발자 | Android Developers
기존 스플래시 화면 구현을 Android 12 이상으로 이전 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 이전에 Android 11 이하에서 맞춤 스플래시 화면을 구현한
developer.android.com
해당 문서를 통해 외부 라이브러리를 가져오고 스타일 정의를 통해 문제를 해결할 수 있었다.
'내일배움캠프 7기 > TIL' 카테고리의 다른 글
| 내일배움캠프 7기 Android TIL 43일차 (2023.09.13) (0) | 2023.09.13 |
|---|---|
| 내일배움캠프 7기 Android TIL 42일차 (2023.09.12) (0) | 2023.09.12 |
| 내일배움캠프 7기 Android TIL 40일차 (2023.09.08) (0) | 2023.09.08 |
| 내일배움캠프 7기 Android TIL 39일차 (2023.09.07) (0) | 2023.09.07 |
| 내일배움캠프 7기 Android TIL 38일차 (2023.09.06) (1) | 2023.09.06 |