! SOPT 8조 친구들과 함께 안드로이드 스터디를 진행하기로 했다!!두둥탁😁 야놀자에 메인화면을 클론 코딩 하면서 MVVM 디자인패턴도 적용해보고 코틀린 문법도 다시한번 점검할 예정이다. 그 첫 단추가 바로 base를 만들어 보기.
앱 개발을 할 때 보면 모든 Activity나 Fragment에 공통적으로 만들어줘야하는 것들이 있다. 이번 차로 앱잼을 하면서 뼈저리게 느꼈던 것이 바로 ViewBinding. 매번 모든 Activity 및 Fragment마다 ViewBinding을 적용했던 적이 있는데 코드도 길어지고 시간 빼앗기는 느낌(?)
이를 해결하고자 base 패키지를 만들어 필수적으로 Activity나 Fragment에 들어갈만한 내용이 들어있는 파일을 만들고, 상속하여 사용할 수 있도록 한다!
먼저 위의 사진과 같이 base라는 패키지를 만들고 그 안에 BaseActivity와 BaseFragment라는 abstract class를 만들어 주었다.
abstract class BaseActivity<T : ViewBinding>(
val bindingFactory: (LayoutInflater) -> T
) : AppCompatActivity() {
private var _binding: T? = null
val binding get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
_binding = bindingFactory(layoutInflater)
setContentView(binding.root)
}
override fun onDestroy() {
super.onDestroy()
_binding = null
}
}
(추상 클래스에 대한 내용은 따로 정리해서 포스팅할 예정)
고차함수 및 람다 참고
BaseActivity는 super type이 ViewBinding인 객체만 T로 받도록 허용한다.
(Generic class 정리 필요)
val bindingFactory: (LayoutInflater) -> T의 경우
bindingFactory라는 변수에 LayoutInflater 객체를 인자로 받아 ViewBinding을 리턴 하는 함수를 할당했다.
LayoutInflater는 xml에 정의된 Resource 를 View 객체로 반환해 주는 역할을 한다.
추상 클래스의 정의를 다 했으면 아래와 같이 Activity에 추상 클래스를 상속시켜주기만 하면 된다.
class MainActivity : BaseActivity<ActivityMainBinding>({ActivityMainBinding.inflate(it)}) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
BaseFragment의 경우에도 BaseActivity와 동일하게 abstract class를 활용한다.
abstract class BaseFragment<T: ViewBinding>: Fragment() {
private var _binding : T? = null
val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = getFragmentBinding(inflater, container)
return binding.root
}
abstract fun getFragmentBinding(inflater: LayoutInflater, container: ViewGroup?) : T
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}