[Android] Fragment의 데이터 통신

2025. 6. 16. 16:51·Android

Fragment가 데이터를 통신하는 방법은 두 가지가 있다.

 

첫 번째로 ViewModel를 이용하여 데이터를 공유하는 방법,

두 번째로는 Fragment Result API를 사용하는 방법이 있다.

 

이때 Bundle 같은 경우 역시 데이터를 전달하고 불러오는 데에 쓰인다.

하지만 생명주기 기반의 UI 데이터 통신에 초점을 맞춘 포스팅이기 때문에 위 두 방법에 대해서 언급하도록 하겠다.😊

 

두 방법의 차이점은 Fragment Result API는 일회성 통신을 지원한다는 것이다!

반면에 ViewModel은 데이터 공유의 주체(Fragment, Activity)의 생명주기에 따라 데이터의 생존(?) 여부가 달라진다.

 

이제 두 방법에 대해 자세히 알아보도록 하자.

 

ViewModel을 통한 데이터 전달

세 경우 모두 ViewModel의 형태는 동일하다.

class ItemViewModel : ViewModel() {
    private val mutableSelectedItem = MutableLiveData<Item>()
    val selectedItem: LiveData<Item> get() = mutableSelectedItem

    fun selectItem(item: Item) {
        mutableSelectedItem.value = item
    }
}

 

- selectItem()으로 mutableSelectedItem을 설정할 수 있고,

- ItemViewModel.selectedItem으로 설정한 mutableSelectedItem을 가져올 수 있다.

 

1. Activity - 하위 Fragment 간 데이터 공유

class MainActivity : AppCompatActivity() {
    private val viewModel: ItemViewModel by viewModels()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        viewModel.selectedItem.observe(this, Observer { item ->
            // Perform an action with the latest item data.
        })
    }
}

class ListFragment : Fragment() {
    private val viewModel: ItemViewModel by activityViewModels()

    fun onItemClicked(item: Item) {
        viewModel.selectItem(item)
    }
}

 

- 하위 Fragment(ListFragment)에서는 액티비티와 데이터를 공유해야 하므로, by activityViewModels()로 ItemViewModel을 위임한다.

- 하위 Fragment(ListFragment)에서는 선언한 viewmodel 내의 함수(selectItem())로 item을 저장한다.

- Activity(MainActivity)는 selectedItem 값이 변경될 때마다 observe(관찰)하여 콜백 함수를 실행한다.

 

2. 한 Activity - 여러 Fragment 간 데이터 공유

class ListFragment : Fragment() {
    private val viewModel: ListViewModel by activityViewModels()
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        viewModel.filteredList.observe(viewLifecycleOwner, Observer { list ->
            // Update the list UI.
        }
    }
}

class FilterFragment : Fragment() {
    private val viewModel: ListViewModel by activityViewModels()
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        viewModel.filters.observe(viewLifecycleOwner, Observer { set ->
            // Update the selected filters UI.
        }
    }

    fun onFilterSelected(filter: Filter) = viewModel.addFilter(filter)

    fun onFilterDeselected(filter: Filter) = viewModel.removeFilter(filter)
}

 

하위의 두 Fragment(ListFragment, FilterFragment) 간의 데이터 통신은 다음과 같다.

- 두 Fragment는 같은 액티비티를 바라보고 있기 때문에 같은 ViewModel 인스턴스를 사용한다.

- 따라서 두 Fragment에 by activityViewModels()로 ListViewModel을 위임한다.

- FilterFragment에서 onFilterSelected(), onFilterDeselected()를 통해 전체 리스트에서 필터를 적용하고 삭제할 수 있다.

- ListFragment에서는 filteredList가 변경될 때마다 observe(관찰)하여 콜백 함수를 실행한다.

 

❗️

만약, 단순히 한 Fragment에서만 ViewModel의 데이터를 가지고 싶으면 by viewModels()로 위임하면 된다.

그렇게 되면, 다른 Fragment로 이동하게 될 때 가지고 있던 ViewModel 객체의 인스턴스는 소멸하게 된다.

 

3. 상위 Fragment - 하위 Fragment 간 데이터 공유

class ListFragment: Fragment() {
    private val viewModel: ListViewModel by viewModels()
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        viewModel.filteredList.observe(viewLifecycleOwner, Observer { list ->
            // Update the list UI.
        }
    }
}

class ChildFragment: Fragment() {
    private val viewModel: ListViewModel by viewModels({requireParentFragment()})
    ...
}

 

[ChildFragment가 ListFragment의 자식 Fragment인 경우]

- ChildFragment에 상위 프래그먼트의 ViewModel 인스턴스를 같이 공유할 것이라고
   { requireParentFragment() } 로 명시해 주어야 한다.

 


Fragment Result API를 통한 데이터 전달

Fragment Result API는 앞에서 언급하였듯이, 일회성 통신을 지원한다.

따라서 Fragment A에서 Fragment B로 데이터를 전달하면

FragmentManager에 데이터가 키-쌍의 형식으로 저장되고, Fragment B는 데이터를 수신한다.

수신한 후 setFragmentResultListener()의 콜백 함수가 실행되면 내부적으로 onFragmentResult() 콜백 함수가 실행된다.

onFragmentResult()는 FragmentManager에 있는 저장된 값을 삭제한다.

 

1. 한 Activity - 여러 Fragment 간 데이터 공유

// Fragment A
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    
    setFragmentResultListener("requestKey") { requestKey, bundle ->
        val result = bundle.getString("bundleKey")
    }
}

// Fragment B
button.setOnClickListener {
    val result = "result"
    setFragmentResult("requestKey", bundleOf("bundleKey" to result))
}

 

[Fragment B가 Fragment A로 데이터를 전달하는 경우]

- Fragment B에서는 requestKey를 가지고 키-값의 bundle을 FragmentManager 내에 저장한다.

- Fragment A에서는 requestKey와 bundle를 수신한다.

- Fragment A에서 setFragmentResultListener() 콜백 함수가 실행된다.

- Fragment A에서 bundle의 키로부터 값을 get한다.

 

2. 상위 Fragment - 하위 Fragment 간 데이터 공유

// 상위 Fragment
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    
    childFragmentManager.setFragmentResultListener("requestKey") { key, bundle ->
        val result = bundle.getString("bundleKey")
    }
}

// 하위 Fragment
button.setOnClickListener {
    val result = "result"
    
    setFragmentResult("requestKey", bundleOf("bundleKey" to result))
}

 

[하위 Fragment가 상위 Fragment로 데이터를 전달하는 경우]

- 하위 Fragment는 requestKey를 가지고 키-값의 bundle을 ChildFragmentManager 내에 저장한다.

- 상위 Fragment는 requestKey와 bundle를 수신한다.

- 상위 Fragment는 childFragmentManager.setFragmentResultListener() 콜백 함수가 실행된다.

- 상위 Fragment는 bundle의 키로부터 값을 get한다.

 

3. Activity - 하위 Fragment 간 데이터 공유

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        supportFragmentManager
                .setFragmentResultListener("requestKey", this) { requestKey, bundle ->
            val result = bundle.getString("bundleKey")
        }
    }
}

 

- MainActivity는 requestKey와 bundle를 수신한다.

- MainActivity는 supportFragmentManager.setFragmentResultListener() 콜백 함수가 실행된다.

- MainActivity는 bundle의 키로부터 값을 get한다.

 

이렇게 ViewModel과 Fragment Result API 를 통해 Fragment 간 데이터를 공유할 수 있는 방법을 알아보았다.

중요한 점은 공유하는 주체에 따라 ViewModel과 Manager의 Scope가 달라질 수 있다는 점이다.

그 외, 전달하고 수신하는 방법은 일관되기 때문이다!

 

:)

 

출처

https://developer.android.com/guide/fragments/communicate?hl=ko

 

'Android' 카테고리의 다른 글

[Android] 클린 아키텍처(Clean Architecture)  (2) 2025.08.11
[Android] Work Manager(+Job Scheduler)  (2) 2025.08.09
[Android] 안드로이드 권장 아키텍처  (4) 2025.07.31
[Android] 스레드(Thread)  (0) 2025.06.12
[Android] 안드로이드의 4대 컴포넌트  (0) 2025.06.11
'Android' 카테고리의 다른 글
  • [Android] Work Manager(+Job Scheduler)
  • [Android] 안드로이드 권장 아키텍처
  • [Android] 스레드(Thread)
  • [Android] 안드로이드의 4대 컴포넌트
jjangsudiary
jjangsudiary
jjangsudiary 님의 블로그 입니다.
  • jjangsudiary
    jjangsudiary 님의 블로그
    jjangsudiary
  • 전체
    오늘
    어제
    • 분류 전체보기 (81) N
      • 이모저모 (0)
        • 회고 (0)
      • Development (17) N
        • 개발 공부 (14) N
        • 프로젝트 (2)
      • Android (10)
        • Compose (1)
      • AI (15)
      • Computer Science (25)
        • 네트워크 (8)
        • 데이터베이스 (10)
        • 운영체제 (6)
        • 자료구조 (0)
        • 컴퓨터구조 (1)
      • Java (9)
        • 디자인패턴 (2)
      • Spring (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    Python
    java
    CS
    os
    백준
    baekjoon
    머신러닝
    android
    운영체제
    딥러닝
    파이썬
    안드로이드
    코딩 테스트
    db
    프로그래머스
    인공지능
    TensorFlow
    Ai
    자바
    database
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
jjangsudiary
[Android] Fragment의 데이터 통신
상단으로

티스토리툴바