소개말
안드로이드 프로젝트를 처음 생성해서 뷰에 데이터를 표현할 때 가장 많이 쓰는 함수는 "View.findViewById(id: Int)" 일 것입니다. 하지만 뷰에 쓰는 컴포넌트가 많아질수록 반복해서 호출해야 하고, 코드가 길어지는 문제를 야기합니다. 우리는 바인딩을 통해 이러한 문제를 해결해보려 합니다.
코틀린에선 findViewById를 쓰지 않고 컴포넌트의 id를 통해 바로 접근할 수 있었지만 androidStudio 4.1에서 kotlin-android-extensions 플러그인이 다양한 문제로 인해 기본적으로 제공되지 않으면서 id를 통해 접근할 수 없게 되었다.
1. 바인딩의 종류
바인딩에는 2가지 방법이 있습니다. 간단하게 뷰를 가져오기만 하는 뷰 바인딩, 바인딩 오브젝트를 통한 양방향 접근이 가능한 데이터 바인딩이 있습니다. 그중 살펴볼 내용은 뷰 바인딩입니다.
2. 뷰 바인딩
정의
뷰 바인딩은 findViewById를 대체할 수 있는 방법 중 하나로 바인딩 클래스를 통해 레이아웃 Id로 모든 뷰의 직접 참조가 가능합니다.
사용법
1. build.gradle 의존성 주입
android {
...
viewBinding {
enabled = true
}
}
// Android Studio 4.0
android {
buildFeatures {
viewBinding = true
}
}
코틀린 익스텐션이 중단됨에 따라 viewBinding의 위치가 buildFeatures로 이동됐습니다
만약 바인딩 클래스를 생성하는 동안 특정 컴포넌트는 바인딩에서 제외하고 싶다면 tools:viewBindingIgnore="true"를 넣어줍니다.
<LinearLayout
...
tools:viewBindingIgnore="true" >
...
</LinearLayout>
2. Activity에서 호출
모듈에 뷰 바인딩을 사용하도록 설정하면 모듈의 각 XML에 대해 바인딩 클래스가 생기게 됩니다. 바인딩 클래스의 이름은 XML 이름을 카멜 케이스로 변환한 뒤 'Binding'를 추가적으로 붙여주게 됩니다.
Activity에서 바인딩 클래스 인스턴스를 설정하려면 onCreate()에서 다음과 같은 절차를 따라야 합니다.
- 생성된 바인딩 클래스에 포함된 정적 inflate() 메서드를 호출합니다. 그러면 활동에서 사용할 바인딩 클래스 인스턴스가 생성됩니다.
- getRoot() 메서드를 호출하거나 Kotlin 속성 구문을 사용하여 루트 뷰 참조를 가져옵니다.
- 루트 뷰를 setContentView()에 전달하여 화면상의 활성 뷰로 만듭니다.
//lateinit으로 스코프를 열어줌
private lateinit var binding: ResultProfileBinding
override fun onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
binding = ResultProfileBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
}
3. Fragment에서 호출
Fragment에서 호출 시 1, 2단계는 같지만 3단계에선 setContentView()에 루트 뷰를 전달 하는 것이 아닌 onCreateView()에서 루트뷰를 반환해주는 차이를 보입니다.
private var binding: ResultProfileBinding? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = ResultProfileBinding.inflate(inflater, container, false)
val view = binding.root
return view
}
override fun onDestroyView() {
super.onDestroyView()
binding = null
}
4. 사용
사용법은 코드단에서 findViewById를 썼던 것처럼 id를 통해 호출하면 됩니다.
binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }
장점
- 코드의 길이를 줄일 수 있다.
- Null Safe : id를 통해 직접 참조하므로 유효하지 않은 id로 인한 nullPointerException이 발생하지 않는다.
- Type Safe : 각 바인딩 클래스에 있는 필드의 유형이 XML 파일에서 참조하는 뷰와 일치한다. 즉, 클래스 변환 예외가 발생할 위험이 없다.
코드를 획기적으로 줄일 수 있고 모듈의 안전을 보장할 수 있는 뷰 바인딩을 살펴봤습니다. 다음엔 양방향 접근이 가능한 데이터 바인딩을 살펴보겠습니다.
'안드로이드 > Binding' 카테고리의 다른 글
데이터 바인딩(Databinding) 표현식 언어와 이벤트 처리 (0) | 2023.03.13 |
---|---|
데이터 바인딩(Databinding)이란? (1) | 2023.03.09 |