[오늘 배운 내용]
-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
'TIL' 카테고리의 다른 글
[TIL] Dialog Fragment / Dialog Fragment 데이터 Fragment로 이동 (0) | 2023.09.06 |
---|---|
[TIL] Fragment에서 ViewBinding 사용하기 (0) | 2023.09.05 |
[TIL] Fragment에 RecyclerView 적용하기 (0) | 2023.09.02 |
[TIL] registerForActivityResult 로 Activity간의 데이터 옮기기 (0) | 2023.09.02 |
[TIL] Lambda를 이용해 Dialog 분리해서 제어하기, FloatingButton으로 RecyclerView 스크롤 상단으로 이동하기 (0) | 2023.08.31 |