RecyclerView의 모든 것! - 2편(ViewHolder수명주기)을 공부하면서 RecyclerdViewPool
을 공유할 수 있다는 사실을 알게됐습니다! 공식문서를 보면 RecycleViewPool을 사용하면 여러 RecycleerView 간에 뷰를 공유할 수 있고,RecycleerViews 간에 뷰를 재활용하려면 RecycledViewPool 인스턴스를 만들고 setRecycledViewPool(재활용ViewPool)
을 사용하면 된다고 나와있다.
즉 여러 RecyclerView들이 동일한ViewHolder를 사용한다면 Pool을 공유해서 ViewHolder를 함께 재사용하기 때문에 불필요한 ViewHolder생성을 줄이고 성능을 최적화할 수 있다.
class Example2Fragment : BaseViewUtil.BaseFragment<FragmentExample2Binding>(com.ummaaack.myapplication.R.layout.fragment_example2) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
binding.rv.adapter=RecyclerView2Adapter()
binding.rv.layoutManager=LinearLayoutManager(requireContext())
}
}
class Example3Fragment : BaseViewUtil.BaseFragment<FragmentExample3Binding>(com.ummaaack.myapplication.R.layout.fragment_example3) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.rv.adapter = RecyclerView2Adapter()
binding.rv.layoutManager = LinearLayoutManager(requireContext())
}
}
하나의 Activity에 두개의 Fragment가 host되어있는 모습입니다. 각 Example2Fragment, Example3Fragment는 RecyclerView를 가지고 있고 RecyclerView2Adapter라는 어댑터를 사용합니다
이때 같은 RecyclerView2Adapter class를 사용하고 viewType도 하나이기때문에 두 RecyclerView는 같은 ViewHolder를 사용하고 있습니다. 하지만 Adapter는 각자의 ViewHolder를 만들어 재활용합니다.
즉 동일한 ViewHolder를 사용하지만 RecycledViewPool을 공유하지 않기때문에 불필요한 onCreateViewHolder가 생성되는 것입니다
onAttacedToRecyclerView
가 호출되어 RecyclerView가 화면에 나타납니다. 그 후 초록색 부분(Example2Fragment)의 Fragment가 호스팅되어 ViewHolder를 생성하고 뒤이어 파란색 부분(Example3Fragment)의 Fragment가 호스팅되어 ViewHolder를 생성합니다RecyclerView의 내부 class인 RecycledViewPool
의 객체를 생성하여 RecyclerView들이 공유할 수 있는 pool을 생성합니다
이후 RecyclerView가 가진 메서드인 setRecycledViewPool()
의 파라미터로 생성했던 RecycledViewPool객체를 전달합니다
class PoolRvActivity : AppCompatActivity() {
val sharedPool = RecyclerView.RecycledViewPool() //pool생성
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_rv)
val sharedPool = RecyclerView.RecycledViewPool()
}
fun getPool():RecyclerView.RecycledViewPool{
return sharedPool
}
}
class Example2Fragment : BaseViewUtil.BaseFragment<FragmentExample2Binding>(com.ummaaack.myapplication.R.layout.fragment_example2) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.rv.adapter = RecyclerView2Adapter(binding.rv) //어댑터 설정
binding.rv.layoutManager = LinearLayoutManager(requireContext())
val activity = requireActivity() as PoolRvActivity
binding.rv.setRecycledViewPool(activity.getPool())
(binding.rv.layoutManager as LinearLayoutManager).recycleChildrenOnDetach = true //
}
}
각 Fragment에서는 메서드로 getPool()의 리턴값인 sharedPool을 전달받아 setRecycledViewPool의 파라미터로 전달합니다.
`
bind될 때마다 pool의 참조값을 로그로 확인해봤더니, 두 adapter가 같은 Pool을 사용하고 있음을 알 수 있었습니다
또한 onCreateViewHolder 호출 회수가 줄어들어든걸 확인했습니다!