728x90
저번까지 한 것에 이어서 선택과제였던 할일 등록 기능을 MVVM 패턴으로 구현하는 걸 혼자서 해보았다.
힌트에 기반하여 저번 코드에서 변경된 부분과 추가된 부분이 있다.
[깃허브]
https://github.com/heesoo-park/ChallengeRecruitAssignment/tree/week1_contain_MVVM
1. 할일 저장소 생성
각각의 프래그먼트에서 사용하던 더미데이터를 object 클래스인 DataStore로 모았다.
그리고 거기서 함수를 만들어 할일을 추가할 수 있도록 했다.
object DataStore {
private val totalTodoList: ArrayList<Todo> = ArrayList()
init {
totalTodoList.add(
Todo(
"title 0",
"description 0"
)
)
totalTodoList.add(
Todo(
"title 1",
"description 1"
)
)
totalTodoList.add(
Todo(
"title 2",
"description 2"
)
)
}
fun getTotalTodoList(): ArrayList<Todo> {
return totalTodoList
}
fun addTodo(todo: Todo) {
totalTodoList.add(todo)
}
}
2. 플로팅 액션 버튼 위치 변경
튜터님의 힌트에 프래그먼트에서 registerForActivityResult를 사용하라는 게 있어서 플로팅 액션 버튼을 메인 액티비티에서 Todo 프래그먼트로 이동했다.
그래서 context가 필요한 부분에 requireContext()를 사용했다.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
...
binding.fabTodoAdd.setOnClickListener {
val intent = Intent(requireContext(), RegisterTodoActivity::class.java)
resultLauncher.launch(intent)
}
}
3. Todo 등록 액티비티에서 입력값 보내고 Todo 프래그먼트에서 받기
등록 버튼을 눌렀을 때 EditText에 입력된 값을 인텐트를 통해 보내줬다.
값은 데이터클래스를 Parcelize해서 객체 자체를 보낼 수 있게 했다.
binding.btnRegisterTodoRegister.setOnClickListener {
val newIntent = Intent()
newIntent.putExtra("todo", Todo(binding.etRegisterTodoTitle.text.toString(), binding.etRegisterTodoDescription.text.toString()))
setResult(RESULT_OK, newIntent)
finish()
}
이건 프래그먼트에서 registerForActivitResult를 통해 받는다.
class TodoFragment : Fragment() {
private lateinit var resultLauncher: ActivityResultLauncher<Intent>
...
override fun onAttach(context: Context) {
super.onAttach(context)
resultLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == RESULT_OK) {
result?.data?.getParcelableExtra("todo", Todo::class.java)
?.let { viewModel.onClickRegister(it) }
}
}
}
...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
...
binding.fabTodoAdd.setOnClickListener {
val intent = Intent(requireContext(), RegisterTodoActivity::class.java)
resultLauncher.launch(intent)
}
}
}
그리고 뷰모델의 onClickRegister 함수를 호출한다.
4. 뷰모델 생성
MVVM 패턴을 적용해야했기에 VIewModel을 만들었다.
새로운 할일이 들어왔음을 알려주는 LiveData를 만들고 변경이 생겼을 때 프래그먼트의 리사이클러뷰 adapter에 notify해줬다.
class TodoViewModel : ViewModel() {
private val _newTodo: MutableLiveData<Todo> = MutableLiveData()
val newTodo: LiveData<Todo> get() = _newTodo
fun onClickRegister(todo: Todo) {
DataStore.addTodo(todo)
_newTodo.value = todo
}
}
private val viewModel by lazy {
ViewModelProvider(this@TodoFragment)[TodoViewModel::class.java]
}
private fun initViewModel() = with(viewModel) {
newTodo.observe(viewLifecycleOwner) {
adapter.notifyItemInserted(DataStore.getTotalTodoList().lastIndex)
}
}
반응형
'Android > StoreInfo' 카테고리의 다른 글
<강의> 안드로이드 앱 개발 심화 - Room (1) | 2024.01.23 |
---|---|
<강의> 안드로이드 앱 개발 심화 - SharedPreferences (1) | 2024.01.23 |
<정리> 챌린지반 과제2 - 1 (0) | 2024.01.23 |
Facade Pattern에 대한 이해 (0) | 2024.01.22 |
<정리> 챌린지반 과제 5 (0) | 2024.01.12 |