개발/Android
Activity에서 Fragment로 값 전달하기
빙수킹
2020. 8. 6. 23:02
Q) MainActivity에서 DestinationFragment로 "value1"과 "value2"를 전달하자
1. 그저그런방법
- 내가 한 비루한 방법.. 이렇게는 하지말자.
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val fragment = DestinationFragment()
fragment.arguments = bundleOf(Pair(DestinationFragment.VALUE_ONE, "value1"), Pair(DestinationFragment.VALUE_TWO, "value2"))
supportFragmentManager.beginTransaction().replace(R.id.fl_fragment, fragment).commit()
}
}
DestinationFragment.kt
class DestinationFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_destination, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val valueOne = arguments?.getString(VALUE_ONE)
val valueTwo = arguments?.getString(VALUE_TWO)
}
companion object {
private const val VALUE_ONE = "VALUE_ONE"
private const val VALUE_TWO = "VALUE_TWO"
}
}
2. 훨씬 좋은 방법
* fragment 객체를 만드는 방법이 다르다.
- fragment가 같은게 2개 이상 생기는걸 방지하기 위해 supportFragmentManager.findFragmentById(id) 를 통해 있는지 찾고, 없는 경우에만 add 또는 replace 해준다.
- fragment가 있는지 찾는 메소드를 DestinationFragment의 companion object에 추가하여 재사용성을 높여주었다.
- newInstance메소드를 DestinationFragment의 companion object에 추가하여 fragment 객체를 만들 수 있도록 했는데, 이렇게 하면 장점은 화면이 넘어갈 때 놓칠 수 있는 VALUE_ONE과 VALUE_TWO를 강제하여 실수를 방지할 수 있다!
- null체크를 let으로 해주었다.
- @JvmStatic: getter, setter을 만들어주는 annotation
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val fragment: DestinationFragment? =
DestinationFragment.findFragment(supportFragmentManager, R.id.contentFrame)
if (fragment == null) {
DestinationFragment.newInstance("value1", "value2").let { fragment ->
supportFragmentManager.beginTransaction()
.add(R.id.contentFrame, fragment)
.commit()
}
}
}
}
DestinationFragment.kt
class DestinationFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_destination, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
arguments?.let {
val valueOne = it.getString(VALUE_ONE)
val valueTwo = it.getString(VALUE_TWO)
}
}
companion object {
private const val VALUE_ONE = "VALUE_ONE"
private const val VALUE_TWO = "VALUE_TWO"
@JvmStatic
fun newInstance(valueOne: String, valueTwo: String) =
DestinationFragment().apply {
arguments = bundleOf(
VALUE_ONE to valueOne,
VALUE_TWO to valueTwo
)
}
fun findFragment(fragmentManager: FragmentManager, @IdRes id: Int): DestinationFragment? {
return fragmentManager.findFragmentById(id) as? DestinationFragment
}
}
}
3. 더더좋은방법
Activity에서와 마찬가지로 findFragment, replaceFragment 역할을 하는 extension 함수를 정의하고, 이를 활용하여 객체를 만드는 코드를 companion object에 넣어주면 된다.
코드는 생략.