프래그먼트 간  데이터 공유

Activity에 포함된 둘 이상의 프래그먼트는 흔히 서로 커뮤니케이션 한다고 알려져 있다. 사용자가 목록에서 항목을 선택하는 프래그먼트와 선택된 항목의 컨텐츠를 표시하는 또 다른 프래그먼트가 있는 split-view(list-detail) 프래그먼트의 일반적인 사례를 가정해보자.

두 프래그먼트가 모두 인터페이스 설명을 정의해야 하고 메인 엑티비티가 두 프래그먼트를 함께 결합해야 하므로 이 사례는 간단히 처리할 수 있는 작업이 아니다.

또한 두 프레그먼트는 모두 다른 프래그먼트가 아직 생성되지 않았거나 표시되지 않은 시나리오도 처리해야 한다.

 

이러한 일반적인 고충은 ViewModel 객체를 사용하면 해결할 수 있다. 이러한 프래그먼트는 다음 샘플 코드와 같이 이 커뮤니케이션 처리하기 위한 활동범위를 사용하여 ViewModel을 공유할 수 있다.

 

class SharedViewModel : ViewModel() {
    val selected = MutableLiveData<Item>()

    fun select(item: Item) {
        selected.value = item
    }
}

class ListFragment : Fragment() {

    private lateinit var itemSelector: Selector

    // Use the 'by activityViewModels()' Kotlin property delegate
    // from the fragment-ktx artifact
    private val model: SharedViewModel by activityViewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        itemSelector.setOnClickListener { item ->
            // Update the UI
        }
    }
}

class DetailFragment : Fragment() {

    // Use the 'by activityViewModels()' Kotlin property delegate
    // from the fragment-ktx artifact
    private val model: SharedViewModel by activityViewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        model.selected.observe(viewLifecycleOwner, Observer<Item> { item ->
            // Update the UI
        })
    }
}

두 프래그먼트는 모두 자신이 포함된 엑티비티를 검색한다. 그러면 각 프래그먼트는 ViewModelProvider를 가져올 때 이 엑티비티 범위가 지정된 동일한 SharedViewModel 인스턴스를 받는다.

이 접근 방법에는 다음과 같은 이점이 있다.

1. Activity는 아무것도 할 필요가 없거나 이 커뮤니케이션에 관해 어떤 것도 알 필요가 없다.

2. Fragment는 SharedViewModel 계약 외에 서로 알 필요가 없다. Fragment 중 하나가 사라져도 다른 Fragment는 계속 평소대로 작동한다.

3. 각 Fragment는 자체 수명 주기가 있으며, 다른 Fragment 수명 주기의 영향을 받지 않는다. 한 Fragment가 다른 Fragment를 대체해도, UI는 아무 문제 없이 계속 작동한다.

 

ViewModel로 로더 대체하기

CursorLoader와 같은 로더 클래스는 앱 UI의 데이터와 데이터베이스 간의 동기화를 유지하는 데 자주 사용된다. ViewModel을 몇 가지 클래스와 함께 사용하여 로더를 대체할 수 있다. ViewModel을 사용하면 UI 컨트롤러가 데이터 로드 작업에서 분리된다.

즉, 클래스 간에 강력한 참조가 적어진다.

 

일반적인 로더 사용 방법 중 하나로, 앱이 CursorLoader를 사용하여 데이터베이스의 내용을 관찰할 수 있다. 데이터베이스에서 값이 변경되면 로더가 자동으로 데이터 새로고침을 트리거하고 UI를 업데이트 한다.

ViewModel은 Room 및 LiveData와 함께 작업하여 로더를 대체한다. ViewModel은 기기 설정이 변경되어도 데이터가 유지되도록 보장한다. 데이터베이스가 변경되면 Room에서 LiveData에 변경을 알리고, 알림을 받은 LiveData는 수정된 데이터로 UI를 업데이트 한다.

 

'Computer engineering > Android Programming' 카테고리의 다른 글

Coroutine_Flow  (0) 2022.07.14
REST API_HttpURLConnection_Coroutine  (0) 2022.07.13
AAC_ViewModel_1  (0) 2022.07.12
MVVM with Clean Architecture  (0) 2022.07.11
4. Architecture Component UI Layer Data Binding_3  (1) 2022.07.10

+ Recent posts