본문 바로가기
Android

[Doit 깡샘의 안드로이드 앱 프로그래밍 with 코틀린] 정리 6 - 뷰 바인딩

by 들풀민들레 2022. 2. 28.
본 글은 [Doit 깡샘의 안드로이드 앱 프로그래밍 with 코틀린 - 이지스퍼블리싱 (2022)] 의 내용을 발췌한 것입니다.

좀더 자세한 내용은 책 혹은 인강을 통해 확인해 주세요.

 

 

 

뷰 바인딩view binding은 레이아웃 XML 파일에 선언한 뷰 객체를 코드에서 쉽게 이용하는 방법입니다. 안드로이드는 UI를 구성할 때 대부분 레이아웃 XML 파일을 이용합니다. 레이아웃 XML 파일에 등록한 뷰는 findViewById() 함수로 얻어서 사용해야 합니다. 이미 06-2절에서 살펴본 내용이지요. 그런데 이 작업은 꽤 귀찮습니다. 한 화면을 구성하는 데만도 많은 뷰가 필요하고, 또 뷰는 대부분 코드에서 이용합니다. 따라서 코드에서 뷰 객체를 선언하고 모두 findViewById() 함수로 하나하나 가져와야 합니다.


그래서 무의미한 반복 작업을 싫어하는 개발자들은 다음과 같이 생각했습니다.


“액티비티에서 findViewById() 함수를 이용하지 않고 레이아웃 XML 파일에 등록된 뷰 객체를 쉽게 사용할 수는 없을까?”
이전부터 많은 개발자가 같은 고민을 했고 이러한 기능을 지원하는 butterknife라는 라이브러리도 등장했습니다. butterknife는 실제 안드로이드 앱 개발에서 많이 이용하던 유명한 라이브러리입니다. 그런데 이제 butterknife 같은 라이브러리의 도움을 받지 않고서도 코드에서 레이아웃 XML에 선언한 뷰를 쉽게 이용할 수 있습니다. 더욱이 butterknife 같은 라이브러리보다 훨씬 간결한 코드로 말이죠.

 

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
	android:layout_width=”match_parent”
	android:layout_height=”match_parent”
	android:orientation=”vertical”>
	<Button
		android:id=”@+id/visibleBtn”
		android:layout_width=”match_parent”
		android:layout_height=”wrap_content”
		android:text=”visible” />
	<TextView
		android:id=”@+id/targetView”
		android:layout_width=”match_parent”
		android:layout_height=”wrap_content”
		android:text=”hello world”
		android:background=”#FF0000”
		android:textColor=”#FFFFFF” />
	<Button
        android:id=”@+id/invisibleBtn”
        android:layout_width=”match_parent”
        android:layout_height=”wrap_content”
        android:text=”invisible” />
</LinearLayout>

이처럼 작성한 레이아웃 XML 파일이 있다고 가정하겠습니다. 이곳에 선언한 뷰 3개를 코드에서 id값으로 얻어서 사용할 수도 있습니다. 그런데 뷰 바인딩 기법을 이용하면 코드에서 훨씬 더 간편하게 뷰 객체를 이용할 수 있습니다.
우선 뷰 바인딩을 사용하려면 그래들 파일에 다음처럼 선언해야 합니다.

 

android {
    (... 생략 ...)
    viewBinding {
        enabled = true
    }
}

build.gradle 파일을 열고 android 영역에 buildFeatures를 선언합니다. 그리고 그 안에 뷰 바인딩을 적용하라는 의미로 viewBinding = true를 설정합니다. 이렇게 하면 레이아웃 XML 파일에 등록된 뷰 객체를 포함하는 클래스가 자동으로 만들어집니다. 즉, 우리가 직접 코드에서 뷰를 선언하고 findViewById() 함수를 호출하지 않아도 이를 구현한 클래스가 자동으로 만들어지므로 이 클래스를 이용해 뷰를 사용하기만 하면 됩니다.


자동으로 만들어지는 클래스의 이름은 레이아웃 XML 파일명을 따릅니다. 첫 글자를 대문자로 하고 밑줄(_)은 빼고 뒤에 오는 단어를 대문자로 만든 후 ‘Binding’을 추가합니다. 예를 들어 다음과 같습니다.


•activity_main.xml → ActivityMainBinding
•item_main.xml → ItemMainBinding

 

자동으로 만들어진 클래스의 inflate() 함수를 호출하면 바인딩 객체를 얻을 수 있습니다. 이때 인자로 layoutInflater를 전달합니다. 그리고 바인딩 객체의 root 프로퍼티에는 XML의 루트 태그 객체가 자동으로 등록되므로 액티비티 화면 출력은 setContentView() 함수에 binding.root를 전달하면 됩니다.

 

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 바인딩 객체 획득
        val binding = ActivityMainBinding.inflate(layoutInflater)
        // 액티비티 화면 출력
        setContentView(binding.root)
        // 뷰 객체 이용
        binding.visibleBtn.setOnClickListener {
        	binding.targetView.visibility = View.VISIBLE
        }
        binding.invisibleBtn.setOnClickListener {
       		binding.targetView.visibility = View.INVISIBLE
        }
    }
}

바인딩 객체에 등록된 뷰 객체명은 XML 파일에 등록한 뷰의 id값을 따릅니다. 즉, XML에 뷰를 <Button android:id=”@+id/visibleBtn” />처럼 등록했다면 바인딩 객체에 visibleBtn이라는 프로퍼티명으로 등록됩니다. 따라서 코드에서는 binding.vibileBtn으로 이용하면 됩니다.


그런데 build.gradle 파일에 뷰 바인딩을 이용하겠다고 선언하면 레이아웃 XML 하나당 바인딩 클래스가 자동으로 만들어지는데, 이때 어떤 레이아웃 XML 파일은 바인딩 클래스로 만들 필요가 없을 수도 있습니다. 이때는 XML 파일의 루트 태그에 tools:viewBindingIgnore=”true”라는 속성을 추가합니다. 이 속성을 추가하면 해당 XML 파일을 위한 바인딩 클래스를 만들지 않습니다.

 

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
    xmlns:tools=”http://schemas.android.com/tools”
    (... 생략 ...)
    tools:viewBindingIgnore=”true”>

앞으로 이 책에서는 뷰를 레이아웃 XML에 선언하고 코드에서 이용할 때는 모두 뷰 바인딩 기법을 사용하겠습니다.