안드로이드 fragment 컴포넌트 통신

이영준·2023년 4월 13일
0

📌 기본적인 액티비티 멤버 접근에 대한 생각

            (requireActivity() as CommunicationActivity).count++
            (requireActivity() as CommunicationActivity).binding.countTv.text = "count : "//??

fragment단에서 자신을 부른 부모 액티비티에서 값을 가져오려면
requireactivity를 하고, 단순히 fragment타입이 아닌 구현된 클래스 타입을 가져와야 하므로 타입캐스팅을 해준다.
하지만 위와 같은 방법은 멤버변수에 자유롭게 접근한다는 점에서 권장되지는 않을 것 같다.
사용하는 액티비티의 변수들이 public 이어야 하기 때문이다.

따라서 몇가지 다른 방법으로 컴포넌트 통신을 해보자!

📌 interface로 접근

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를 사용한다.

++Require... get...차이

        requireActivity() //getActivity했을 때 null 처리를 해줌
        activity // == getActivity는 null 처리 없음
        
        requireContext() 
        getContext()
        context

📌 Bundle에 넣어 전달

    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 메서드를 가져와 작성하여 보낸다.

profile
컴퓨터와 교육 그사이 어딘가

0개의 댓글