Fragment
- TextView나 Button처럼 액티비티 화면을 구성하는 뷰
- 프래그먼트는 액티비티처럼 동작한다.
- 즉, 액티비티에 작성할 수 있는 코드들은 다 가능함
Fragment 구현
Fragment Class
import androidx.fragment.app.Fragment
class OneFragment : Fragment() {
lateinit var binding: FragmentOneBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentOneBinding.inflate(inflater, container, false)
return binding.root
}
}
- fragment는 activity와 다르게 주로 onCreateView를 이용하여 View를 그린다.
- 생명주기에서 다루지만, onCreate() 후에 fragment가 전환될 때마다 onCreatView가 호출된다.
MainActivity
- xml
<LinearLayout android:id=”@+id/fragment_content” android:layout_width=”match_parent” android:layout_height=”match_parent” android:orientation=”vertical”> </LinearLayout>
- class
val fragmentManager: FragmentManager = supportFragmentManager val transaction: FragmentTransaction = fragmentManager.beginTransaction() val fragment = OneFragment() transaction.add(R.id.fragment_content, fragment) transaction.commit()
- Fragment를 동적으로 제어하려면 FragmentManager로 만든 FragmentTransaction 클래스를 이용해야 함
- add(): 새로운 프래그먼트를 화면에 추가함
- replace(): 추가된 프래그먼트를 대체함
- remove(): 추가된 프래그먼트를 제거
- commit(): 화면에 적용
Fragment 생명주기
- onCreateView()는 프래그먼트의 화면을 구성할 때 호출된다.
- 이 함수가 반환하는 뷰를 프래그먼트 화면에 출력함
- onResume()이후 프래그먼트가 대체될 때 두 가지 방식으로 진행된다.
- back stack을 이용할 때
- onPause() → onStop() → onDestoryView() → onDestory() → onDetach() 함수까지 호출
- 이 과정을 통해 fragment가 완벽히 제거가 된다.
- back stack을 이용하지 않을 때
- onPause() → onStop() → onDestoryView() 함수까지 호출
- fragment가 화면에서 살하진 후 back stack에 추가될 때 onDestroyView를 호출하며 완벽히 제거되지 않는다.
- 뒤로가기 버튼을 누르면 다시 onCreatView()부터 활성 상태까지의 함수들이 호출된다.
- back stack을 이용할 때
- back stack
- fragment가 화면에 보이지 않는 순간 제거하지 않고 저장했다가 다시 이용할 수 있게 하는 기능
transaction.addToBackStack(null)
을 통해 설정 가능함
🎯 Fragment 전환
- Fragment를 동적으로 제어하려면 FragmentManager로 만든 FragmentTransaction 클래스를 이용해야 한다.
- 이때, fragment를 view에 추가하는 것은 add, 대체하는 것은 replace를 사용하여 전환한다.
- 간단한 예제를 통해 fragment to fragment 전환을 확인해보자.
val fragment = TwoFragment() supportFragmentManager .beginTransaction() .replace(R.id.fragment_content, fragment) .commit()
🎯 Fragment 끼리의 데이터 전달
- Bundle을 이용해서 전달한다.
- 전송 fragment
val bundle = Bundle() bundle.putString("key", "value") val passBundleBFragment = PassBundleBFragment() passBundleBFragment.arguments = bundle parentFragmentManager.beginTransaction() .replace(R.id.fragment_container_bundle, PassBundleFragment()) .commit()
- 받는 곳에서는 activity에서 Extra data를 받아오듯 이용하면 된다.
- Fragment Result API를 이용하여 전달한다.
- 전송 fragment
val result = "result" setFragmentResult("requestKey", bundleOf("bundleKey" to result)) parentFragmentManager .beginTransaction() .replace(R.id.fragment_container_bundle, PassBundleFragment()) .commit()
- 수신 fragment
setFragmentResultListener("requestKey") { requestKey, bundle -> val result = bundle.getString("bundleKey") }
🎯 Fragment 간 뒤로가기는 어떻게 해야할까?
- back stack을 이용한다.
- 이는 프래그먼트가 화면에서 사라질 때 스택에 프래그먼트를 저장하고 있다가
- 뒤로가기를 눌렀을 때 다시 꺼내오는 기능을 제공한다.
- 사용방법은
transaction.addToBackStack(null)
을 통해 사용이 가능하다.val fragment = TwoFragment() supportFragmentManager .beginTransaction() .replace(R.id.fragment_content, fragment) .addToBackStack(null) .commit()
- 사용방법은
- 뒤로가기를 눌렀을 때 다시 꺼내오는 기능을 제공한다.
- 전송 fragment