본문 바로가기

Language/Kotlin

[Android/ Kotlin] findViewById 함수를 대체하는 뷰 결합

기존에 xml파일의 View를 가져오는 방식은 다음 두 가지였다.

  1. findViewById() 함수 이용
  2. View의 이름을 통해 자동 import (Kotlin Sythetics)

결론부터 말하면 1번은 Android Studio에서 권장되지 않는 기능이며, 2번은 2021년 9월 중 삭제될 예정이다.

 

일단 2번 기능은 kotlin-android-extensions 라는 plugin을 통해 사용할 수 있었다.

하지만 권장 옵션인 View Binding(뷰 결합)을 계속 지원하기 위해서 해당 기능을 공동으로 사용하지 않을 것이라고 한다.

 

그렇다면 권장 옵션인 뷰 결합을 Activity에서 사용하는 방법을 알아보자.

 

뷰 결합은 모듈 단위로 사용되기 때문에 build.gradle(Module: app_name.app) 파일에 들어가 다음 코드를 작성한다.

android {
        ...
        viewBinding {
            enabled = true
        }
    }

이후 위에 뜨는 Sync Now를 눌러주면 뷰 결합을 위한 사용 설정이 완료된다. 

사용 설정된 뷰 결합은 모듈에 있는 모든 XML layout 파일의 바인딩 클래스(결합 클래스)를 생성한다.

각 결합 클래스에는 루트 뷰 및 ID가 있는 모든 뷰의 참조가 포함되므로, 우리는 이 결합 클래스를 통해 레이아웃에 있는 View를 직접 참조할 수 있게 된다.

 

만약 뷰 결합을 사용하지 않는 XML 파일이 있다면 루트 뷰에 viewBindingIgnore 속성을 추가하면 된다.

<LinearLayout
            ...
            tools:viewBindingIgnore="true" >
        ...
    </LinearLayout>

 

결합 클래스의 이름은 XML 파일의 이름을 카멜 표기법으로 변환하고 끝에 'Binding'을 추가하여 생성된다.

카멜 표기법 (Camel Case)
여러 단어를 연달아 사용할 때 각 단어의 첫 글자를 대문자로 적되, 맨 앞에 오는 글자는 소문자로 표기하는 것

예를 들어 레이아웃 파일 이름이 activity_listener.xml인 경우 결합 클래스의 이름은 ActivityListenerBinding이 된다.

 

이제 Activity에서 결합 클래스를 이용해 hello라는 이름의 Text View에 접근해보자.

package com.example.app1

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.app1.databinding.ActivityListenerBinding

// 결합 클래스 인스턴스 생성 단계 - 1
private lateinit var binding: ActivityListenerBinding

class Listener : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_listener)

        // 결합 클래스 인스턴스 생성 단계 - 2
        binding = ActivityListenerBinding.inflate(layoutInflater)
        // root View (Linear Layout) 참조
        val view = binding.root
        setContentView(view)

        // 뷰 결합으로 ID가 hello인 TextView 접근
        binding.hello.text = "바인딩 성공!"
    }
}

이렇게 뷰 결합을 하고 나면 findViewById 메서드를 사용할 필요 없이 바로 view를 참조할 수 있다.

 

그렇다면 Android Studio에서 findViewById 메서드보다 뷰 결합을 권장하는 이유가 무엇일까?

  1. Null 안전 : 뷰 결합은 뷰의 직접 참조를 생성하므로 유효하지 않은 뷰 ID로 인해 null 포인터 예외가 발생할 위험이 없다. 또한 레이아웃의 일부 구성에만 뷰가 있는 경우 결합 클래스에서 참조를 포함하는 필드가 @Nullable로 표시된다.
  2. 유형 안전: 각 바인딩 클래스에 있는 필드의 유형이 XML 파일에서 참조하는 뷰와 일치합니다. 즉, 클래스 변환 예외가 발생할 위험이 없습니다 (아직 이건 무슨 말인지 모르겠다..)

 

참고한 글

Android Developers, View Binding
제임스리의 네이버 블로그
카레유의 티스토리

'Language > Kotlin' 카테고리의 다른 글

[Kotlin] 접근자 메소드, 게터(Getters)와 세터(Setters)  (0) 2021.08.15