뷰바인딩을 쓰는 이유
안드로이드 코드에서 xml에 있는 UI에 접근을 하기 위해서는 FindViewById를 이용합니다.
@SuppressWarnings("TypeParameterUnusedInFormals")
@Override
public <T extends View> T findViewById(@IdRes int id) {
return getDelegate().findViewById(id);
}
//ex)
val button : Button = findViewById<Button>(R.id.button)
이 방법도 나쁘지는 않지만 일일이 findViewById() 함수로 하나하나 찾아서 가져와야 한다는 애로사항이 있었습니다.
3.5 버전까지는 개발자들이 findViewById를 사용했었지만, Butter knife라는 라이브러리나 extension을 이용해서 불편함을 해결했다고 합니다. 그러던 중 3.6 버전에서 이를 대체할 수 있는 ViewBinding(뷰결합)이 나오게 됩니다.
코틀린에서는 이 뷰 바인딩 작업조차 안 하고 id를 바로 변수처럼 사용할 수 있는 Kotlin Synthetic이 생겼지만 여러 가지 이유로 4.1 버전에서 Kotlin Synthetic은 deprecated 되었습니다. 현재는 자바와 코틀린 둘 다 ViewBinding을 사용합니다.
뷰바인딩을 사용한다면 어떻게 달라질까요? UI에 더욱 쉽게 접근할 수 있습니다.
//findViewById예시
val button1 = findViewById<Button>(R.id.button)
//ViewBindingd예시
val button2 = binding.button
이처럼 뷰바인딩을 사용한다면 더욱 쉽게 접근을 할 수 있습니다.
사용방법
그렇지만 뷰바인딩을 사용하기 위해서는 사전 작업이 필요합니다.
app단의 gradle 파일에 뷰 바인딩 설정해줘야 합니다.
android {
(...생략...)
(...1번 방법 ...)
buildFeatures {
viewBinding = true
}
(...2번 방법 ...)
viewBinding{
enabled = true
}
}
이렇게 gradle 파일에 뷰바인딩을 성정해 줬다면 XML 파일에 등록된 뷰 객체를 포함하는 클래스가 자동으로 만들어집니다. 클래스가 자동으로 만들어진다는 것은 코드에서 뷰를 선언하고 findViewById() 함수를 호출하지 않아도 구현한 클래스가 자동으로 만들어지므로 그 클래스를 이용해서 사용하면 된다는 것입니다. 자동으로 만들어지는 클래스의 이름은 레이아웃 XML 파일명을 따릅니다.
클래스의 이름의 형식은 첫 글자를 대문자로 하고 언더바( '_' )는 빠지고 그다음 첫 글자를 대문자로 바꾸고 'Binding'을 추가합니다. 예를 들면 item_main.xml이라는 레이아웃이 ItemMainBinding이라는 클래스가 된다는 말입니다.
// 바인딩 레이아웃 임포트
import com.tistory.test_project.databinding.ItemMainBinding
// 바인딩 객체 획득
val binding = ActivityMainBinding.inflate(layoutInflater)
// 액티비티 화면 출력
setContentView(binding.root)
// 뷰 객체 이용
binding.visibleBtn.setOnClickListener { ... }
binding.helloText.text = ""
위방법은 ViewBinding 코틀린 코드에서 사용하는 방법입니다. 자동으로 만들어진 클래스의 inflate() 함수를 호출하면 바인딩 객체를 얻을 수 있습니다. 인자는 layoutInflater를 전달하면 됩니다. 바인딩 객체의 root 프로퍼 티티에는 XML의 루트 태그 객체가 자동으로 등록되므로 액티비티 화면 출력은 setContentView() 함수에 binding.root를 전달해 주면 됩니다.
장점
ViewBinding은 이처럼 편할 뿐만 아니라 여러 장점이 있습니다.
- Null 안정성: 뷰의 직접 참조를 생성하므로 유효하지 않은 뷰 ID로 인해 null 포인터 예외가 발생할 위험이 없습니다. 또한 레이아웃의 일부 구성에만 뷰가 있는 경우 결합 클래스에서 참조를 포함하는 필드가 @Nullable로 표시됩니다.
- Type 안정성: 각 바인딩 클래스에 있는 필드의 유형이 XML 파일에서 참조하는 뷰와 일치합니다. 즉, 클래스 변환 예외가 발생할 위험이 없습니다.
안드로이드를 좀 더 공부하다 보면 데이터 바인딩을 공부하게 될 것입니다.
그러다 보면 데이터 바인딩을 써야 할지 뷰바인딩을 써야 하지 고민할 때가 있을 것입니다. 둘 모두 뷰를 직접 참조하는 데 사용할 수 있는 결합 클래스를 생성합니다. 하지만 뷰 바인딩은 보다 단순한 사용 사례를 처리하기 위한 것이며 데이터 결합에 비해 다음과 같은 이점을 제공합니다
- 더 빠른 컴파일: 뷰 바인딩에는 주석 처리가 필요하지 않으므로 컴파일 시간이 더 짧습니다.
- 사용 편의성: 뷰 바인딩에는 특별히 태그 된 XML 레이아웃 파일이 필요하지 않으므로 앱에서 더 신속하게 채택할 수 있습니다. 모듈에서 뷰 바인딩을 사용 설정하면 모듈의 모든 레이아웃에 뷰 결합이 자동으로 적용됩니다.
반대로 뷰 바인딩에는 데이터 결합과 비교할 때 다음과 같은 제한사항이 있습니다. 뷰 바인딩은 레이아웃 변수 또는 레이아웃 표현식을 지원하지 않으므로 XML 레이아웃 파일에서 직접 동적 UI 콘텐츠를 선언하는 데 사용할 수 없습니다. 뷰 바인딩 데이터 결합을 지원하지 않습니다.
위 사항을 고려할 때 일부 사례에서는 프로젝트에 뷰 바인딩과 데이터 바인딩을 모두 사용하는 것이 가장 좋습니다. 고급 기능이 필요한 레이아웃에는 데이터 바인딩을, 고급 기능이 필요 없는 레이아웃에는 뷰 바인딩을 사용할 수 있습니다.
참고
https://todaycode.tistory.com/29
https://developer.android.com/topic/libraries/view-binding?hl=ko
'안드로이드 > 안드로이드' 카테고리의 다른 글
[Android/Kotlin] 리사이클러뷰(RecyclerView) 스크롤 이벤트 (2) | 2023.08.31 |
---|---|
[Android/Kotlin] 알림(Notification)아이디 채널아이디 (2) | 2023.08.30 |
[Android/Kotlin] 리사이클러뷰(RecyclerView) 어댑터 이야기 (0) | 2023.08.08 |
[Android/Kotlin] ActivityResultLauncher는 무었일까요? (0) | 2023.08.07 |
[안드로이드] context는 무었인가 (0) | 2022.04.30 |