[Android 앱 개발 숙련] 5. 프래그먼트의 데이터 전달

0
post-thumbnail

[Android 앱 개발 숙련] 5. 프래그먼트의 데이터 전달

📌참고자료: Why to use Fragment Arguments in Android | Medium

Fragment Recreation

  • Fragment recreation:
    when fragment instance has to be destroyed and be initiated again
    -> fragment constructer will be called again
    -> fragment will live a whole new lifecycle
  • Configuration change triggers recreation
    -> recreation of currently visible fragment (and activity)
class MainActivity : AppCompatActivity(){ 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        if (savedInstanceState == null) {
            supportFragmentManager.beginTransaction()
                .replace(R.id.container, RecreationExampleFragment())
                .commit()
        }
    }
}
  • Activity will create fragment...
    • in onCreate()
    • when restoring activity's state (savedInstanceState)

Don'ts when using fragments

  • 우리가 필요로하는 데이터를 파라미터로 갖는 cunstom constructor를 정의하는 경우
    -> not guaranteed to be always safe
    -> The android system requires each fragment to have a default constructor with no parameter
    (default constructor is called on fragment recreation)
class BadFragment1(
    // will crash, on recreation because no default constructor is defined
    private val textToShow: String
): Fragment()
  • 우리가 필요로하는 데이터를 프로퍼티로 갖도록 정의하는 경우
    -> value will be lost in fragment recreation
class BadFragment2: Fragment() {
    // Will be reset to empty string after recreation
    var textToShow: String = ""
}

Fragment arguments

  • It is strongly recommended to supply arguments with setArguments and later retrieved by the Fragment with getArguments
    -> These arguments are automatically saved and restored alongside the Fragment
  • Fragment argument로 사용할 수 있는 data type에 제한 존재
    • Only simple data types are supported (ex. String, Int, ...)
    • Parcelables, Serializables
  • newInstance() 패턴
class GoodFragment: Fragment() {
    // retrieve value from arguments in custom getter 
    private val textToShow: String
        get() = requireArguments().getString(ARG_TEXT_TO_SHOW)
            ?: throw IllegalArgumentException("Argument $ARG_TEXT_TO_SHOW required")
    companion object {
        // the name for the argument
        private const val ARG_TEXT_TO_SHOW = "argTextToShow"
        // Use this function to create instances of the fragment
        // and set the passed data as arguments
        fun newInstance(textToShow: String) = GoodFragment().apply {
            arguments = bundleOf(
                ARG_TEXT_TO_SHOW to textToShow
            )
        }
    }
}

(1) Activity -> Fragment 데이터 전달

  • newInstance 패턴 사용

(2) Fragment -> Fragment 데이터 전달

  • newInstance 패턴 사용

(3) Fragment -> Activity 데이터 전달

  • 콜백 인터페이스(FragmentDataListner) 정의
interface FragmentDataListener {
    fun onDataReceived(data: String)
}
  • 데이터를 보내는 Fragment
    • 프래그먼트가 액티비티에 attach될 때, 액티비티가 콜백 인터페이스(FragmentDataListner)를 구현하는지 확인
      class SecondFragment : Fragment() {
      	private var listener: FragmentDataListener? = null
      	//...
        	override fun onAttach(context: Context) {
             super.onAttach(context)
             if (context is FragmentDataListener) {
                 listener = context
             } else {
                 throw RuntimeException("$context must implement FragmentDataListener")
             }
          }
          //...
          override fun onDestroyView() {
             super.onDestroyView()
             _binding = null
             listener = null
         }
      }
    • 콜백 인터페이스의 onDataReceived 메서드를 호출하여 데이터 전달
        val dataToSend = "Hello from SecondFragment!"
         listener?.onDataReceived(dataToSend)
  • 데이터를 받는 Activity
    • 콜백 인터페이스(FragmentDataListner) 구현
      class MainActivity : AppCompatActivity(), FragmentDataListener {
          //...
         override fun onDataReceived(data: String) {
             // Fragment에서 받은 데이터를 처리
             Toast.makeText(this, data, Toast.LENGTH_SHORT).show()
         }
      }
profile
Be able to be vulnerable, in search of truth

0개의 댓글