(requireActivity() as CommunicationActivity).count++
(requireActivity() as CommunicationActivity).binding.countTv.text = "count : "//??
fragment단에서 자신을 부른 부모 액티비티에서 값을 가져오려면
requireactivity를 하고, 단순히 fragment타입이 아닌 구현된 클래스 타입을 가져와야 하므로 타입캐스팅을 해준다.
하지만 위와 같은 방법은 멤버변수에 자유롭게 접근한다는 점에서 권장되지는 않을 것 같다.
사용하는 액티비티의 변수들이 public 이어야 하기 때문이다.
따라서 몇가지 다른 방법으로 컴포넌트 통신을 해보자!
interface CommunicationCallback {
fun onPlusCount()
}
접근할 수 있는 인터페이스를 만들어 이 인터페이스 구현으로 액티비티 멤버에 접근한다.
activity가 interface를 implement 하거나,
class CommunicationActivity : AppCompatActivity(), CommunicationCallback
...
override fun onPlusCount() {
count++;
binding.countTv.text = "Count : $count"
}
혹은
val add = object : CommunicationCallback{
override fun onPlusCount() {
TODO("Not yet implemented")
}
}
anonymous nested class 형태로 빼와서 구현할 수도 있다. 이번엔 전자의 방법대로 한다.
이 구현된 communicationcallback 인터페이스를 fragment에 넘겨주고,
communicationFragment = CommunicationFragment()
communicationFragment.listener = this
supportFragmentManager.beginTransaction()
.replace(R.id.frameLayout_for_comm, communicationFragment).commit()
fragment에서 이 인터페이스를 받아서
lateinit var listener : CommunicationCallback
binding.plusButton.setOnClickListener{
listener.onPlusCount()
}
구현체의 onPlusCount를 사용한다.
requireActivity() //getActivity했을 때 null 처리를 해줌
activity // == getActivity는 null 처리 없음
requireContext()
getContext()
context
fun changeFragmentView(fragment: Int, param: String) {
val transaction = supportFragmentManager.beginTransaction()
when (fragment) {
1 -> {
transaction.replace(R.id.fragment_container, Fragment1.newInstance(param)).commit()
}
2 -> {
transaction.replace(R.id.fragment_container, Fragment2.newInstance(param)).commit()
}
}
}
fragment들은
companion object{
@JvmStatic
fun newInstance(param : String)=
Fragment2().apply {
arguments = Bundle().apply {
putString(PARAM, param)
}
}
}
new Instance 구현하여 argument로 param을 전달받을 수 있도록 한다.
그리고
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
getView()?.findViewById<Button>(R.id.goto_fragment2)?.setOnClickListener {
fragmentNavigationActivity.changeFragmentView(FragmentNavigationActivity
.SECOND_FRAGMENT, "fragment 1 to fragment 2")
}
requireView().findViewById<TextView>(R.id.text_view1).text = value
}
다른 fragment에 데이터를 넣어 보낼 일이 있으면 activity에서 가져온 changeFragmentView 메서드를 가져와 작성하여 보낸다.