728x90

Activity(액티비티)  → Fragment(프래그먼트) 로 데이터 전송하는 경우 

 

메인액티비티

더보기
class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.run {
            btnFragment1.setOnClickListener {
                val data = "액티비티에서 보낸 데이터"
                val fragment1 = FirstFragment.newInstance(data)
                setFragment(fragment1)
            }
            btnFragment2.setOnClickListener {
                val data = "액티비티에서 보낸 데이터2"
                val fragment2 = SecondFragment.newInstance(data)
                setFragment(fragment2)
            }
        }

    }

    private fun setFragment(frag: Fragment) {
        supportFragmentManager.beginTransaction().apply {
            replace(R.id.fragment_Container, frag)
            setReorderingAllowed(true) // 애니메이션과 전환이 올바르게 작동하도록 트랜잭션과 관련된 프래그먼트의 상태 변경을 최적화
            addToBackStack("") // BackStack을 추가해줌 프래그먼트 뒤로가기 History
            commit()
        }
    }

}

 

FirstFragment

더보기
private const val ARG_PARAM1 = "param1"

class FirstFragment : Fragment() {
    private lateinit var binding: FragmentFirstBinding
    private var param1: String? = null
    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 = FragmentFirstBinding.inflate(inflater)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.tvFragment1Text.text = param1

    companion object {
        fun newInstance(param1: String) =
            FirstFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                }
            }
    }
}

SecondFragment

더보기
private const val ARG_PARAM2 = "param2"

class SecondFragment : Fragment() {
    private lateinit var binding: FragmentSecondBinding
    private var param2: String? = null
  
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param2 = it.getString(ARG_PARAM2)
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentSecondBinding.inflate(inflater)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.tvFragment2Text.text = param2
    }

    companion object {
        fun newInstance(param2: String) =
            SecondFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM2, param2)
                }
            }
    }
}

Fragment → Fragment 데이터 전송하는 경우 

 

FirstFragment

더보기
private const val ARG_PARAM1 = "param1"

class FirstFragment : Fragment() {
    private lateinit var binding: FragmentFirstBinding
    private var param1: String? = null
    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 = FragmentFirstBinding.inflate(inflater)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.run {
            tvFragment1Text.text = param1

            btnSendToFragment2.setOnClickListener {
                val data = "From Fragment1 data"
                val fragment2 = SecondFragment.newInstance(data)
    
                requireActivity().supportFragmentManager.beginTransaction().apply {
                    replace(R.id.fragment_Container, fragment2)
                    addToBackStack(null) // BackStack을 추가해줌 프래그먼트 뒤로가기 History
                    commit()
                }
                
                
//                (activity as MainActivity).supportFragmentManager.beginTransaction().apply {
//                    replace(R.id.fragment_Container, fragment2)
//                    addToBackStack(null)
//                    commit()
//                }
                
                
                
            }

        }

    }

    companion object {
        fun newInstance(param1: String) =
            FirstFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                }
            }
    }
}

Fragment Activity 데이터 전송하는 경우 (interface로 listener를 만들어야함)

더보기
private const val ARG_PARAM2 = "param2"

class SecondFragment : Fragment() {
    private lateinit var binding: FragmentSecondBinding
    private var param2: String? = null
    private var listener: DataReceiverListener? = null

    override fun onAttach(context: Context) {
        super.onAttach(context)
        if (context is DataReceiverListener) {
            listener = context
        } else {
            throw RuntimeException("$context")
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param2 = it.getString(ARG_PARAM2)
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentSecondBinding.inflate(inflater)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.run {
            tvFragment2Text.text = param2

            btnSendToActivity.setOnClickListener {
                val data = "From Fragment2 data"
                listener?.dataReceived(data)
            }
        }
    }

    companion object {
        fun newInstance(param2: String) =
            SecondFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM2, param2)
                }
            }
    }
}

interface DataReceiverListener {
    fun dataReceived(data: String)
}

MainActivity

더보기
class MainActivity : AppCompatActivity(),DataReceiverListener {
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.run {
            btnFragment1.setOnClickListener {
                val data = "액티비티에서 보낸 데이터"
                val fragment1 = FirstFragment.newInstance(data)
                setFragment(fragment1)
            }
            btnFragment2.setOnClickListener {
                val data = "액티비티에서 보낸 데이터2"
                val fragment2 = SecondFragment.newInstance(data)
                setFragment(fragment2)
            }
        }

    }

    private fun setFragment(frag: Fragment) {
        supportFragmentManager.beginTransaction().apply {
            replace(R.id.fragment_Container, frag)
            setReorderingAllowed(true)
            addToBackStack("")
            commit()
        }
    }

    override fun dataReceived(data: String) {
        Toast.makeText(this, "$data", Toast.LENGTH_SHORT).show()
    }
}

Fragment1  → Fragment2 → Fragment1 → Fragment2로 데이터 보내기 → Activity로 데이터 보내기

 

 

requireContext, requireActivity

Fragment 에서 context 나 activity 를 사용하는 상황이 fragment 가 attach 되서 정상적인 lifecycle 이라면 requireXXX 를 쓰는 것이 바람직하다.

+ Recent posts