안드로이드/불명예의 전당

[Android/Kotlin] ViewPager2와 FragmentStateAdapter를 이용했을 때, UI에서 adatper를 통해 Fragment를 add 했을 때 추가된 프래그먼트가 곧바로 생성되지 않는 점 해결.

란서 2022. 6. 16. 14:34

문제점


 

  • FriendAddAdapter
class FriendAddAdapter(fm: FragmentManager, lifecycle:Lifecycle) : FragmentStateAdapter(fm, lifecycle) {
    var list : List<Fragment> = listOf()

    override fun getItemCount(): Int = list.size


    override fun createFragment(position: Int): Fragment {
        return list[position]
    }

    fun addReceptionFragment(fragment: Fragment, friendCode:Long) {
        Log.i(TAG,"addReceptionFragment")
        fragment.arguments = Bundle().apply {
            putLong("ReceptionKey", friendCode)
        }

        list = list + listOf(fragment)
    }


    fun addDispatchFragment(fragment: Fragment, friendCode:Long) {
        Log.i(TAG,"addDispatchFragment")
        fragment.arguments = Bundle().apply {
            putLong("DispatchKey", friendCode)
        }
        list = list + listOf(fragment)
    }
    
    companion object {
        const val TAG = "프렌드_애드_어댑터"
    }


}

 

  • FriendAddFragment
      val adapter = FriendAddAdapter(childFragmentManager, lifecycle)
        binding.viewPageFriendAdd.adapter = adapter

      adapter.addDispatchFragment(FriendDispatchFragment(), convertHexStringToLongFormat(profile.friendCode))
      adapter.addReceptionFragment(FriendReceptionFragment(), convertHexStringToLongFormat(profile.friendCode))

 

 

이 때 생성된 두 프래그먼트 중 하나

  • DispatchFragment
class FriendDispatchFragment() : Fragment() {

    private lateinit var binding : FragmentFriendDispatchBinding

    private lateinit var viewModelFactory: FriendDispatchViewModelFactory
    private lateinit var viewModel: FriendDispatchViewModel

    private var friendCode : Long? = null

    override fun onStart() {
        super.onStart()
        Log.i(TAG,"onStart()")
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.i(TAG,"onDestroy")
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_friend_dispatch, container,false)

  		...

        return binding.root
    }

    companion object {
        const val TAG = "프렌드_디스패치_프래그먼트"
        const val KEY = "DispatchKey"
    }
}

 

 

실행 결과 

 

2022-06-16 13:19:08.671 8889-8889/com.example.solaroid I/프렌드_애드_어댑터: addDispatchFragment
2022-06-16 13:19:08.671 8889-8889/com.example.solaroid I/프렌드_애드_어댑터: addReceptionFragment

와 같이 FriendAddAdapter의 함수가 호출될 때 찍히는 로그만 나올뿐

실제 프래그먼트가 시작될 때 onStart() 로그가 곧바로 찍히지 않는다.

 

-> 즉 adapter에서 createFragment() 메서드를 통해 프래그먼트가 제대로 viewPager에  뿌려지지 않았다는 것.

 

 

문제해결


주 UI에서 adapter.add함수를 통해 프래그먼트가 추가될 때 리스트가 변동되었지만, 해당 리스트가 변동된지 모르기 때문에 프래그먼트의 생성을 반영하지 못해 createFragment()가 호출되지 않는다는 생각이 들었다 .

 

따라서 var list = listOf<Fragment>() 데이터 변수에 

    var list : List<Fragment> = listOf()
        set(value) {
            field = value
            notifyDataSetChanged()
        }

 

다음과 같은 코드를 구현하여 해결