앱을 만들 때, 화면을 만들고 나면 화면의 기능을 구현해야 한다. 화면에 있는 버튼을 눌렀을 때 다른 화면으로 이동하거나 데이터와 화면이 연결되도록 말이다. 이러한 작업을 쉽게 도와주는 기술 중 하나가 바로 dataBinding이다.
나는 여태 viewBinding을 써왔는데, 이번에 dataBinding에 대해 알게 되었다. 따라서 이번 포스트에서는 DataBinding의 사용 방법을 정리해보려고 한다.
데이터바인딩의 장점은 명확하다. viewBinding 대신 DataBinding을 사용하면 XML 파일과 데이터가 더욱 밀접하게 연결되므로 편리하다는 것!
android {
buildFeatures {
dataBinding true
}
}
lateinit var fragmentIntroBinding: FragmentIntroBinding
lateinit var mainActivity: MainActivity
화면이 생성되는 onCreateView 메서드에서 XML 레이아웃 파일을 인플레이트하여 화면에 표시한다. 이때, DataBindingUtil의 inflate 메서드를 사용하여 데이터바인딩을 적용한다.
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
// fragmentAddContentBinding = FragmentAddContentBinding.inflate(inflater)
fragmentAddContentBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_add_content, container, false)
contentActivity = activity as ContentActivity
return fragmentAddContentBinding.root
}
그런데 여기서 DataBindingUtil의 inflate 메서드가 어떤 역할을 하는지 궁금해졌다. 이 메서드는 왜 항상 따라오는 걸까?
그래서 inflate 에 대해 찾아보았다.
inflate 메서드의 매개변수는 4개로, 각각의 역할은 아래와 같다.
: parent 매개변수로 ViewGroup 타입의 객체가 전달된다. 이 ViewGroup 객체는 인플레이트된 뷰가 속하게 될 “부모” 역할을 하며, 주로 인플레이트된 뷰를 추가할 상위 레이아웃을 의미한다.
그런데 ViewGroup을 “Container”라고 부르는 이유가 궁금했다. 어차피 root 레이아웃을 가리키는 것 같은데, 왜 굳이 root가 아닌 Container라고 지칭할까?
찾아보니 다음과 같은 차이가 있었다.
따라서 Container가 더 넓은 의미로, 꼭 최상위(root) 레이아웃을 지칭하지 않더라도 다양한 상황에서 UI 요소를 담는 “상자” 역할을 한다는 점에서 ViewGroup을 가리킬 때 Container라고 부르는 것이다.
그런데 어차피 최상위 root 에 올 수 있는 요소는 layout과 관련된 요소밖에 없기 때문에 일반적으로 ‘최상위 레이아웃 = root’ 라고 간주한다고 한다.
: attachToparent 는 인플레이트 된 뷰를 부모에 자동으로 추가할지 여부를 지정하는 매개변수다. 그럼 true 로 설정하게 되면 자동으로 부모에 추가되어 화면에 표시된다는 건데, 그게 더 좋은거 아닌가?
왜 false가 일반적인 설정인건지?
이것도 찾아보니 다음과 같은 이유가 있었다.
예를 들어 로그인 버튼을 누르면 로그인 화면을, 회원가입 버튼을 누르면 회원가입 화면을 보여주는 상황처럼, attachToParent 값을 false로 두면 사용자가 누른 버튼에 따라 다른 화면을 보여줄 수 있다. 반대로 true로 설정하면 두 화면이 동시에 겹쳐 보일 수 있다는 것. 아주 중요한 사유였다.
이로써 inflate 에 대해 궁금한 것들이 풀렸다. 그냥 그런가보다- 하고 넘어갈 수 있었던 것들이 명확해지니까 한결 낫다!