본문 바로가기

TIL

[TIL] Fragment간의 데이터 Bundle 통하여 옮기기, Bundle을 사용하는 이유.

[오늘 배운 내용]

-1- Fragment간의 데이터 이동

  • 이전에 Activity간의 데이터 이동을 RegisterForActivityResult를 통해 Intent로 데이터를 이동했으나 Fragment간의 이동에서는 Intent를 통해 데이터를 이동하지 않고 Bundle() 을 통해 데이터를 이동한다.
  • Fragment간의 데이터 이동에서 Intent를 사용하지 않고 Bundle을 통해 이동하는 이유는 다음과 같다.

 

  • Fragment의 독립성 유지
    • Fragment는 Activity 내에서 재사용 가능한 모듈로 설계되었는데, Intent를 사용하여 데이터를 전달하게 되면 Fragment와 Activity가 결합되어 다른 Activity로 전환할 때 코드의 재사용성과 모듈화 측면에서 제약이 생길 수 있다.
  • 안전한 타입 지정
    • Intent는 Extra 데이터를 Key-Value의 쌍으로 전달한다. 이러한 방식은 컴파일러에 오류가 발생하지 않고 런타임에서 예외가 발생할 수 있지만 Bundle은 컴파일 타임에 타입 검사가 가능하므로 안전한 타입 지정이 가능하다. 따라서 Bundle을 사용해서 명시적으로 데이터의 타입을 지정함으로써 코드 안정성을 높일 수 있다.
  • 생명주기 관리
    • Fragment는 자체적인 생명주기를 가지고 있으며, 여러 상황에서 생성 및 소멸될 수 있습니다.Intent를 사용하여 데이터를 전달하는 경우, Fragment가 재생성되거나 복원될 때 문제가 발생할 수 있다. 그러나 Bundle을 활용하여 데이터를 전달할 경우 시스템이 알아서 상태 저장 및 복원을 처리해주므로 생명주기 관리에 용이하다.
  • 직접적인 통신
    • Fragment는 독립적인 단위로 작동하며, 다른 Fragment와 직접적으로 통신해야 할 때가 많다. Intent는 주로 Activity 간의 통신에 사용되지만, Fragment 간의 통신에는 적합하지 않다. 반면에 Bundle을 사용하면 Fragment 간의 직접적인 통신을 더욱 명확하게 할 수 있다.

 

 

번들(Bundle)

  • Kotlin에서 Bundle은 데이터를 저장하고 전달하기 위한 객체이다. Activity나 Fragment 등의 다른 컴포넌트로 데이터를 전달하거나 상태를 저장 및 복원하는 데에 활용된다.
  • Bundle은 Key-Value의 쌍으로 데이터를 저장한다. Key는 문자열 형태로 식별자 역할을 하며, Value는 다양한 타입의 데이터를 담을 수 있다.

 

 

  • Bundle의 주요 메소드
  • putXXX(key,value)
    • 값을 Bundle에 추가한다. XXX부분에는 putString() 와 같이 타입이름이 들어가며  putParcelable()와 같이 인터페이스를 구현하는 객체도 저장할 수 있어 직렬화 가능한 객체도 전달이 가능하다.
  • getXXX()
    • Bundle에 해당 타입의 값을 가져온다.
  • containsKey()
    • 특정 key가 bundle에 포함되어 있는지 Boolean값을 반환한다.
  • remove()
    • 특정 키와 해당 값을 삭제한다.

 

 

 

데이터 옮기기

  • Fragment 내의 Button을 클릭하면 해당 FragmentA 내의 EditText에 입력한 값 데이터를 FragmentB로 넘겨서 해당 데이터의 값이 들어간 TextView가 보여지는 화면을 만들어보자.
  • 1. 프로젝트 생성 후 gradle에서 ViewBind, Fragment 추가 및 적용해주기
  • 2. Fragment 생성 및 UI 설정 후 Fragment가 보여질 Activity에 Fragment 적용
class MainActivity : AppCompatActivity() {
    private lateinit var binding : ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        setFragment(FirstFragment())

    }
    private fun setFragment(fragment: Fragment){
        supportFragmentManager
            .beginTransaction()
            .replace(R.id.main_frame_layout,fragment)
            .addToBackStack(null)
            .commit()
    }
}

 

 

  • 3. Fragment A에서 데이터 Bundle에 저장하고 Fragment 전환하는 이벤트 만들기
// FirstFragment

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentFirstBinding.inflate(inflater,container,false)

        binding.firstTvOne.setOnClickListener {
            val secondFragment = SecondFragment()
            val inputData = binding.editTextText.text.toString()
            val bundle = Bundle()
            bundle.putString("data",inputData)

            secondFragment.arguments = bundle
            parentFragmentManager.beginTransaction()
                .replace(R.id.main_frame_layout,secondFragment)
                .addToBackStack(null)
                .commit()
        }

        val view = binding.root
        return view
    }

 

 

  • 4. FragmentB에서 넘겨온 데이터 받아서 TextView에 적용
// SecondFragment

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentSecondBinding.inflate(inflater,container,false)

        val bundle = arguments
        if (bundle != null){
            val data = bundle.getString("data")
            binding.secondTextView.text = data
            Log.d("TAG", "data: ${data}")
        }

        val view = binding.root
        return view
    }

 

 

 

요약

  • 버튼 클릭 메서드에서 데이터를 포함한 Bundle 객체를 생성하고, 해당 Bundle을 FragmentB의 arguments로 설정한다.
  • key-value의 쌍으로 되어있는 데이터를 putXXX메서드를 통해 데이터를 저장한다.
  • 데이터를 받는 Fragment로 이동하여 onCreate() 메서드 내부에서 FragmentA로 부터 전달된 arguments를 받아온다.
  • 받아온 Bundle이 null인지 확인한 후 getXXX 메서드를 통해 key에 해당하는 데이터를 추출한다.
  • 추출된 데이터를 이용하여 작업.

 

 

적용화면

 

 

 

 

 


 

[오늘 복습한 내용]

1. Fragment에서 ViewBinding 적용하기

  • 여기 내부안에다가 적으면 나중에 찾기 힘들 것 같아서 따로 글에 작성

 

 


[오류,에러 등등]

1. 책상에 음료수 흘렸다.

 


[느낀 점]

1. 요즘 밖에 나가는 게 귀찮아 졌다.

 

2. 재밌는데 어렵다.

 

3. 꾸준히 집중하는 시간을 늘려나가는 것 같아서 만족스럽다

 

 


[Reference]

 

 

// Fragment

 

https://velog.io/@l2hyunwoo/Android-%EA%B8%B0%EB%8A%A5-%EA%B5%AC%ED%98%84-5

https://curryyou.tistory.com/385

https://velog.io/@sysout-achieve/Android-Fragment%EA%B0%84-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EB%8B%AC-%EB%B0%A9%EB%B2%95%EB%93%A4#3-viewmodel%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-data-%EC%A0%84%EB%8B%AC