문제상황
1. List 를 보여주는 Fragment에서 data 추가를 위해 DialogFragment 호출
2. DialogFragment 에서 저장 버튼 클릭 시, interface 를 통해 List 를 보여주는 Fragment 로 데이터 전달
3. DialogFragment 종료
4. Room Database 에 insert 한 후, 최신 List 가져와 UI 에 보여주기
그런데 4번의 최신 List 를 가져와 UI 에 보여주기 부분이 제대로 이루어지지 않음
나의 예상
Fragment -> DialogFragment 이동 시, Fragment 의 생명주기 : onResume()
DialogFragment -> Fragment 이동 시, Fragment 의 생명주기 : onResume() -> onPause() -> onResume() 의 상태
결과
Fragment -> DialogFragment 이동 시, Fragment 의 생명주기 : onResume()
DialogFragment -> Fragment 이동 시, Fragment 의 생명주기 : onResume()
나의 예상 != 결과인 이유
A fragment that displays a dialog window, floating on top of its activity's window. This fragment contains a Dialog object, which it displays as appropriate based on the fragment's state.
공식홈페이지를 통해 DialogFragment는 activity 위에서 floating 되어 보여지므로 DialogFragment 가 종료되어도 Fragment 의 상태가 변하지 않는 다는 것을 알게되었다.
시도 1 - 실패
DialogFragment 의 onDismiss() 메소드를 오버라이드하여 dismiss 되었을 때 callback interface 를 호출하여 데이터 넘기기
시도 2 - 성공
DialogFragment 가 아닌 Activity 로 Dialog 형태로 만들어 보여주기
결과적으로는 기존의 Fragment 를 가지고 있는 Activity 가 아닌 다른 Activity(Dialog의 모습) 를 호출하여 registerForActivityResult 를 사용하여 data 받아 처리하였다.
ListFragment
class ListFragment : Fragment() {
// Dialog(다른 Activity)에서 결과를 받아 처리하기 위한 변수
private lateinit var getResultTopic: ActivityResultLauncher<Intent>
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
getResultTopic = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
result.data?.let {
val topic = Topic(
it.getStringExtra("topic")!!,
it.getStringExtra("color")!!,
it.getStringExtra("date")!!)
(presenter as TopicPresenter).saveTopic(topic)
}
} else {
println("===== getResultTopic - Failed =====")
}
}
}
}
ListFragment 에서 data 추가 버튼 클릭 시
toolbar.setOnMenuItemClickListener { menu ->
when (menu.itemId) {
R.id.main_add -> {
val topicAddIntent = Intent(view.context, TopicAddActivity::class.java)
getResultTopic.launch(topicAddIntent)
true
}
else -> false
}
}
DialogActivity 에서 저장 버튼을 눌렀을 때(data 전달)
val moveTopicList = Intent(this, TopicListFragment::class.java)
moveTopicList.putExtra("topic", topic.topic)
moveTopicList.putExtra("color", topic.color)
moveTopicList.putExtra("date", topic.registDate)
setResult(Activity.RESULT_OK, moveTopicList)
배운점
1. DialogFragment 는 Fragment 의 lifecycle 에 영향을 미치지 않는다.
2. Fragment 의 pause / resume 은 기본적으로 Host Activity 를 따라간다.
2-1. Fragment 를 replace / remove 할 때에는 pause 상태를 가진다.
3. registerForActivityResult 사용
'Android > note' 카테고리의 다른 글
[Android] Room Database 마이그레이션 도오전 (0) | 2023.08.30 |
---|---|
[Android] SupportFragmentManager 파도타기 (0) | 2023.06.18 |
[Android] Android Studio의 open file list 가 안보일때 (0) | 2022.07.10 |
[Android] Firebase Realtime Database를 REST로 사용할 때 key값에 "이제는" 접근한 사람 (0) | 2022.04.12 |
[android] Firebase Realtime Database를 REST로 사용할 때 key값에 접근하지 못한 사람 (0) | 2022.04.06 |