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()
}
}
requireContext, requireActivity
Fragment 에서 context 나 activity 를 사용하는 상황이 fragment 가 attach 되서 정상적인 lifecycle 이라면 requireXXX 를 쓰는 것이 바람직하다.