
프로퍼티를 세팅해주는 코드를 다른 클래스에게 위임하는 디자인 패턴
val delegate by Delegate()
이런 식으로 선언하고 delegate 변수를 위임 프로퍼티, Delegate() 객체를 위임 객체라고 부름
kotlin convention 중에 하나
by 뒤에 오는 위임 객체가 getValue(), setValue()를 구현하면 위임 객체로서의 기능을 할 수 있음
언어의 특정 기능을 특정 이름의 함수와 연결해주는 기능
ex. plus라는 이름의 메서드를 만들면 + 연산자를 plus라는 함수와 연결해줘서 a.plus(b)를 a+b로 사용할 수 있음
Activity의 기능을 무엇인가?
여기서 view를 inflate하는 부분이 Activity마다 비슷하기 때문에 by 연산자로 만들어 수 있지 않을까 생각했다.
class DataBindingActivityDelegate<out T : ViewBinding>(
@LayoutRes private val layoutRes: Int,
) {
private var _binding: T? = null
operator fun getValue(thisRef: AppCompatActivity, property: KProperty<*>): T {
_binding = _binding ?: DataBindingUtil.setContentView(thisRef, layoutRes)
return _binding!!
}
}
사용할 때는
private val binding: ActivityRegisterBinding by DataBindingActivityDelegate<ActivityRegisterBinding>(
R.layout.activity_register
)
class ViewBindingActivityDelegate<out T : ViewBinding>(
private val inflater: (LayoutInflater) -> T,
) {
private var _binding: T? = null
operator fun getValue(thisRef: AppCompatActivity, property: KProperty<*>): T {
_binding = _binding ?: inflater(thisRef.layoutInflater)
return _binding!!
}
}
사용할 때는
override val binding: ActivityDetailBinding by ViewBindingActivityDelegate {
ActivityDetailBinding.inflate(it)
}
class DataBindingFragmentDelegate<T : ViewBinding>(
@LayoutRes private val layoutRes: Int,
) {
private var _binding: T? = null
operator fun getValue(thisRef: Fragment, property: KProperty<*>): T? {
_binding = _binding ?: DataBindingUtil.inflate(
thisRef.requireActivity().layoutInflater,
layoutRes,
thisRef.view?.parent as? ViewGroup,
false
)
return _binding
}
operator fun setValue(thisRef: Fragment, property: KProperty<*>, value: T?) {
_binding = value
}
}
사용할 땐
class HomeFragment : GoBongFragment<FragmentHomeBinding, HomeViewModel>() {
private var _binding: FragmentHomeBinding? by DataBindingFragmentDelegate(R.layout.fragment_home)
override val binding: FragmentHomeBinding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}