TIL
TIL 38일차
김태준(Android_3기)
2024. 4. 11. 19:43
프래그먼트
액티비티 위에서 동작하는 인터페이스
하나의 프래그먼트를 여러 액티비티에서 재사용할 수 있음
프래그먼트 사용 예제
- 프래그먼트 파일 생성
- xml 파일 정의
- MainActivity에 Fragment 추가하기
프래그먼트의 데이터 전달
Activity > Fragment 데이터 전달
- 보내는 코드
binding.run { fragment1Btn.setOnClickListener{ // [1] Activity -> FirstFragment val dataToSend = "Hello First Fragment! \n From Activity" val fragment = FirstFragment.newInstance(dataToSend) setFragment(fragment) } fragment2Btn.setOnClickListener { // [1] Activity -> SecondFragment val dataToSend = "Hello Second Fragment!\n From Activity" val fragment = SecondFragment.newInstance(dataToSend) setFragment(fragment) }
- 받는 코드
private var param1: String? = null
companion object {
@JvmStatic
fun newInstance(param1: String) =
// [1] Activity -> FirstFragment
FirstFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// [1] Activity -> FirstFragment
binding.tvFrag1Text.text = param1
}
Fragment > Fragment 데이터 전달
- 보내는 코드
// [2] Fragment -> Fragment binding.btnGofrag2.setOnClickListener{ val dataToSend = "Hello Fragment2! \n From Fragment1" val fragment2 = SecondFragment.newInstance(dataToSend) requireActivity().supportFragmentManager.beginTransaction() .replace(R.id.frameLayout, fragment2) .addToBackStack(null) .commit() }
- 받는 코드
private const val ARG_PARAM1 = "param1"
class SecondFragment : Fragment() {
private var param1: String? = null
private var _binding: FragmentSecondBinding? = null
private val binding get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentSecondBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// [2] Fragment -> Fragment
binding.tvFrag2Text.text = param1
}
companion object {
@JvmStatic
fun newInstance(param1: String) =
// [1] Activity -> FirstFragment
SecondFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
}
}
}
override fun onDestroyView() {
super.onDestroyView()
// Binding 객체 해제
_binding = null
}
}
Fragment > Activity 데이터 전달
- 보내는 코드
private const val ARG_PARAM1 = "param1" interface FragmentDataListener { fun onDataReceived(data: String) } class SecondFragment : Fragment() { // [3] SecondFragment -> Activity private var listener: FragmentDataListener? = null private var param1: String? = null private var _binding: FragmentSecondBinding? = null private val binding get() = _binding!! override fun onAttach(context: Context) { super.onAttach(context) // [3] SecondFragment -> Activity if (context is FragmentDataListener) { listener = context } else { throw RuntimeException("$context must implement FragmentDataListener") } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) arguments?.let { param1 = it.getString(ARG_PARAM1) } } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = FragmentSecondBinding.inflate(inflater, container, false) return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // [2] Fragment -> Fragment binding.tvFrag2Text.text = param1 // [3] SecondFragment -> Activity binding.btnSendActivity.setOnClickListener{ val dataToSend = "Hello from SecondFragment!" listener?.onDataReceived(dataToSend) } } companion object { @JvmStatic fun newInstance(param1: String) = // [1] Activity -> FirstFragment SecondFragment().apply { arguments = Bundle().apply { putString(ARG_PARAM1, param1) } } } override fun onDestroyView() { super.onDestroyView() // Binding 객체 해제 _binding = null listener = null } }
- 받는 코드
class MainActivity : AppCompatActivity(), FragmentDataListener {
private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
binding.run {
fragment1Btn.setOnClickListener{
// [1] Activity -> FirstFragment
val dataToSend = "Hello First Fragment! \n From Activity"
val fragment = FirstFragment.newInstance(dataToSend)
setFragment(fragment)
}
fragment2Btn.setOnClickListener {
// [1] Activity -> SecondFragment
val dataToSend = "Hello Second Fragment!\n From Activity"
val fragment = SecondFragment.newInstance(dataToSend)
setFragment(fragment)
}
}
setFragment(FirstFragment())
}
private fun setFragment(frag : Fragment) {
supportFragmentManager.commit {
replace(R.id.frameLayout, frag)
setReorderingAllowed(true)
addToBackStack("")
}
}
// [3] SecondFragment -> Activity
override fun onDataReceived(data: String) {
// Fragment에서 받은 데이터를 처리
Toast.makeText(this, data, Toast.LENGTH_SHORT).show()
}
}