[개념] Fragment(프래그먼트)간 데이터 전달

쓰리원·2022년 5월 4일
0
post-thumbnail

1. bundle과 FragmentManager로 전달 예제

bundle을 이용하여 프레그먼트간의 데이터 전송 예제 입니다.

1. MainActivity.kt

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val transaction: FragmentTransaction = supportFragmentManager.beginTransaction()
        val transaction2 : FragmentTransaction = supportFragmentManager.beginTransaction()

        val SenderFragment = SenderFragment()
        transaction.replace(R.id.sender, SenderFragment)
        transaction.commit()

        val RecieverFragment = RecieverFragment()
        transaction2.replace(R.id.receiver, RecieverFragment)
        transaction2.commit()
    }
}

2. SenderFragment.kt

class SenderFragment : Fragment() {

    private lateinit var binding: FragmentSenderBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = FragmentSenderBinding.inflate(layoutInflater)

    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return binding.root
    }

    override fun onResume() {
        super.onResume()
        
        binding.btnYes.setOnClickListener {
            val bundle = Bundle()
            bundle.putString("key", "yes")
            val recieverFragment = RecieverFragment()
            recieverFragment.arguments = bundle
            parentFragmentManager.beginTransaction().
            replace(R.id.receiver, recieverFragment).commit()
        }
        
        binding.btnNo.setOnClickListener {
            val bundle = Bundle()
            bundle.putString("key", "no")
            val recieverFragment = RecieverFragment()
            recieverFragment.arguments = bundle
            parentFragmentManager.beginTransaction().
            replace(R.id.receiver, recieverFragment).commit()
        }
    }
}

3. RecieverFragment.kt

class RecieverFragment : Fragment() {

    private lateinit var binding: FragmentRecieverBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = FragmentRecieverBinding.inflate(layoutInflater)
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment

        arguments?.getString("key")?.let {
            binding.textView.text = it
        }

        return binding.root
    }
}

2. Fragment의 FragmentManager에서 setResultListener() API를 사용

1. SenderFragment.kt

class SenderFragment : Fragment() {

    private lateinit var binding: FragmentSenderBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = FragmentSenderBinding.inflate(layoutInflater)
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return binding.root
    }

    override fun onResume() {
        super.onResume()
        binding.btnYes.setOnClickListener {
            val result = "Yes"
            val bundle = bundleOf("bundleKey" to result)
            setFragmentResult("requestKey", bundle)
        }
        binding.btnNo.setOnClickListener {
            val result = "No"
            val bundle = bundleOf("bundleKey" to result)
            setFragmentResult("requestKey", bundle)
        }
    }
}

2. RecieverFragment.kt

class RecieverFragment : Fragment() {

    private lateinit var binding: FragmentRecieverBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = FragmentRecieverBinding.inflate(layoutInflater)

        setFragmentResultListener("requestKey") { requestKey, bundle ->
            bundle.getString("bundleKey")?.let {
                binding.textView.setText(it)
            }
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return binding.root
    }
}

자세한 설명 : https://velog.io/@ilil1/FragmentResultApi-%EB%9E%80

3. Navigation의 safe-args로 전달

1. FirstFragment.kt

class FirstFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_first, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val item = ArrayList<Item>()
        item.add(Item(111, "changed"))

        view.findViewById<Button>(R.id.button_first).setOnClickListener {
            val action = FirstFragmentDirections.actionFirstFragmentToSecondFragment(item.toTypedArray())

            findNavController().navigate(action)
        }
    }
}

2. SecondFragment.kt

class SecondFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_second, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val args: SecondFragmentArgs by navArgs()
        val itemList = args.item.toCollection(ArrayList())

        view.findViewById<TextView>(R.id.textview_second).text = "${itemList[0].id} ${itemList[0].name}"
        view.findViewById<Button>(R.id.button_second).setOnClickListener {
            findNavController().navigate(R.id.action_SecondFragment_to_FirstFragment)
        }
    }
}

자세한 설명 : Navigation-safe-args

4. Fragment간 ViewModel로 데이터 전달

자세한 설명 : Fragment간-ViewModel로-데이터-전달

5. reference

https://developer.android.com/training/basics/fragments/pass-data-between?hl=ko

profile
가장 아름다운 정답은 서로의 협업안에 있다.

0개의 댓글