findViewById()
메서드를 사용해 View
의 ID가 주어졌을 때 해당 뷰에 대한 참조를 반환하는 작업을 통해 사용할 수 있지만 앱에 뷰가 많이 추가되면서 UI가 복잡해질 경우 번거로워질 수 있다.
이런 부분에서 편의를 위해 View Binding이 제공된다. 간단한 사전 작업이 요구되지만 UI의 뷰에서 메서드를 더 쉽고 빠르게 호출할 수 있다. 사전 작업은 Gradle에서 뷰 바인딩 설정과 약간의 코드 추가가 필요하다.
앱의 build.gradle
파일의 android
섹션을 찾는다. 아래 코드를 찾고 상단의 Sync Now를 누른다.
buildFeatures {
viewBinding = true
}
findViewById()
와 View Binding의 차이를 보여주는 그림이다.
findViewById()
는 각 뷰 마다 호출되어야 한다. 반면에 View Binding은 바인딩 객체 하나가 모든 뷰의의 참조를 가진다.
이제 MainActivity.kt
를 수정해야 한다.
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
}
}
클래스에서 바인딩 객체의 최상위 변수를 선언하는 코드이다. 변수 binding
은 MainActivity
클래스의 여러 메서드에서 사용될 수 있기 때문에 해당 레벨에서 선언된다.
lateinit var binding: ActivityMainBinding
lateinit
키워드는 코드가 변수를 사용하기 전에 먼저 초기화될 것임을 명시한다. 변수를 초기화하지 않으면 앱이 비정상 종료된다.
activity_main.xml
레이아웃에서 Views
에 액세스하는 데 사용할 binding
객체를 초기화한다.
binding = ActivityMainBinding.inflate(layoutInflater)
Activity의 콘텐츠 뷰를 설정하는 코드이다. 뷰 바인딩을 사용하지 않을 때는 레이아웃의 리소스 ID인 R.layout.activity_main
이 전달되지만 우리는 뷰 바인딩을 사용하고 있기 때문에 뷰 계층 구조의 루트인 binding.root
를 전달한다.
setContentView(binding.root)
TextView
가 하나 있고 Button
2개로 해당 TextView
의 visibility
를 On/Off 하는 화면을 만들었다.
코드는 간단하다.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context=".MainActivity">
<TextView
android:id="@+id/txtTargetView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TargetView"
android:visibility="invisible" />
<Button
android:id="@+id/btnVisible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Visible" />
<Button
android:id="@+id/btnInvisible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Invisible" />
</LinearLayout>
바인딩 객체에 등록된 뷰 객체명은 XML 파일에 등록한 뷰의 id
값을 따른다. 위 XML 코드에서 btnVisible
로 등록하여 바인딩 객체에 btnVisible
라는 프로퍼티명으로 등록된다.
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.btnVisible.setOnClickListener {
binding.txtTargetView.visibility = View.VISIBLE
}
binding.btnInvisible.setOnClickListener {
binding.txtTargetView.visibility = View.INVISIBLE
}
}
}
버튼이 클릭되면
Binding 클래스의 이름은 XML 파일의 이름을 카멜 표기법으로 변환하고 이름 끝에 'Binding'을 추가하여 생성된다. 마찬가지로 각 뷰를 위한 참조는 (
_
)을 삭제하고 뷰 이름을 카멜 표기법으로 변환하여 생성된다. 예를 들어activity_main.xml
은ActivityMainBinding
이 되고binding.textView
로@id/text_view
에 액세스할 수 있다.
선생님 너무 유익합니다.