-
View Binding 사용해보기Android/Android 2020. 11. 5. 17:38
Kotlin 1.4.20 버전에서 Kotlin Android Extensions Compiler 플러그인이 Deprecated 됬다
왜 Kotlin Android Extensions Compiler 플러그인을 Deprecated 했을까?
- 글로벌 네임스페이스로 노출이 되어 현재 Activity 에서 사용중이지 않은 View 를 참조 할 수 있다.
이에 Null Safty 하지 않다. - 오직 Kotlin 언어로만 접근 및 사용이 가능하다.
그러면 무엇으로 대체를 해야 할까?
- View Binding
- View Binding 은 Binding 뿐만 아니라 View Lookup 에도 권장되지만 Android Kotlin Extensions와 비교할 때 오버헤드가 약간 추가된다.
- Kotlin Extensions 와 비교했을 때, View Lookup 과 타입 안전성의 컴파일 시간 체크가 추가되었다.
- findViewById
- 예전부터 계속 해오던 방식
findViewById를 계속 쓰기에는 매우 unpretty 하다. 그래서 ViewBinding 을 한번 써보도록 하겠다.
목차
- 뷰 바인딩은 무엇인가?
- 뷰 바인딩 준비하기
- 액티비티에서 뷰 바인딩 사용하기
- 프래그먼트에서 뷰 바인딩 사용하기
- Include 태그에서 뷰 바인딩 사용하기
뷰 바인딩은 무엇인가?
- 뷰 바인딩은 View 와 상호 작용하는 코드를 보다 쉽게 작성할 수 있는 기능이다.
- 모듈에서 뷰 바인딩을 활성화하면 해당 모듈에 있는 각 XML 레이아웃 파일에 대한 바인딩 클래스를 생성한다.
- 바인딩 클래스의 인스턴스는 해당 레이아웃에 ID가 있는 모든 뷰에 대한 직접 참조를 포함한다.
- 뷰 바인딩은 뷰가 XML 있는지 탐지하고 @Nullable 속성을 생성하기에 Null-safe 하다.
- View Binding은 Java 및 Kotlin과 함께 작동한다.
무엇보다 가장 큰 장점은 NullSafty 하다는 소리인데 예를 들어 이런 경우를 생각해 보도록 하자.
ex ) RegisterActivity, LoginActivity 에 edit_password 라는 뷰를 둘다 가지고 있을 때, 둘중 하나의 액티비티에서 참조를 하려면 아래와 같이 뜰 것이다.
물론 잘못쓰면 다시 고치면 되지만 매번 실수를 할 수 있는거고 이러한 문제는 런타임에서 나타난다는 것이다.
이러한 문제점은 버그를 수정해서 기쁘다는 표정으로 빌드를 하고 테스트하다가 죽는 상황이 발생한다. ( 히히... )
뷰 바인딩 준비하기
그러면 뷰바인딩을 한번 사용해 보도록 하자
우선 build gralde 파일에 아래와 같이 추가해주도록 하자 그러면 이제 끝이다.
android { buildFeatures { viewBinding true } }
만약에 Binding 클래스를 생성하기 싫은 레이아웃은 아래와 같이 viewBindingIgnore 를 true 해주면 된다.
<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" tools:viewBindingIgnore="true" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <LinearLayout>
추가적으로 테스트를 하기 위해 아래와 같이 코드를 구성하였다.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout ... > <TextView ... /> <ImageView ... /> <Button ... /> </LinearLayout>
액티비티에서 뷰 바인딩 사용하기
뷰 바인딩을 활성화 하기위해서는 onCreate() 에서 아래의 2가지를 진행 해주면 된다.
- 생성된 바인딩 클래스에 포함되어있는 정적 함수인 inflate 를 호출해줘서 생성된 바인딩 클래스를 해당 액티비티에서 사용하도록 한다.
- setContentView에 위에서 생성한 binding 객체로 부터 getRoot() 나 코틀린 문법을 통해 root 객체를 얻어 넣어주면 된다.
class MainActivity : AppCompatActivity() { private lateinit var binding : ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) } }
binding 변수에 접근을 하면 아래와 같이 아까 레이아웃에서 설정한 3개의 뷰 컴포넌트들이 보인다.
무려 Nullable 하다! 즉, 안전하다는 소리다.
사용은 엄청 간단하다. 그냥 평소에 하던대로 사용을 하면 된다.
binding.button.setOnClickListener { binding.textView.text = "Hello?" binding.imageView.setImageDrawable( resources.getDrawable( R.drawable.ic_launcher_foreground, null ) ) }
프래그먼트에서 뷰 바인딩 사용하기
프래그먼트를 하나 생성하고 바로 바인딩 객체를 생성해 주도록 하자
private lateinit var binding: FragmentSubMainBinding override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { binding = FragmentSubMainBinding.inflate(layoutInflater, container, false) return binding.root }
바인딩 객체를 생성하는 거 자체는 액티비티와 다를 것이 없다.
굳이 뽑자면 프래그먼트는 onCreateView에서 뷰 객체를 생성하는 것이다.
override fun onStart() { super.onStart() binding.button1.setOnClickListener { Toast.makeText(this@SubMainFragment.context, binding.button1.text, Toast.LENGTH_SHORT) .show() } // ... }
onStart 에서 바인딩 객체를 통해 리스너 및 부가적인 작업을 해주면된다.
Include 태그에서 뷰 바인딩 사용하기
Include 태그로 삽입 된 뷰의 경우는 더욱이 쉽게 바인딩이 가능하다.
우선 아래의 코드를 프래그먼트나 액티비티에 삽입해준다.
<include android:id="@+id/layout_include" android:layout_width="600dp" android:layout_height="600dp" layout="@layout/include_layout"/>
필자는 프래그먼트 객체에 넣어보았고 프래그먼트 클래스로 가서 아래와 같이 변수 선언 및 초기화를 해주면 된다.
private lateinit var binding: FragmentSubMainBinding private lateinit var includeBinding: IncludeLayoutBinding override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { binding = FragmentSubMainBinding.inflate(layoutInflater, container, false) includeBinding = binding.layoutInclude return binding.root }
끝.
마무리
간단하게 ViewBinding을 사용해 보았다 이렇게 간단하게 사용이 가능하고 Android Kotlin Extension 을 사용 하면서 nullable 하게 접근하지 않아도 되고 findViewByID를 사용하지 않아도 된다.
다들 뷰 바인딩 하자.
'Android > Android' 카테고리의 다른 글
테스트코드를 왜 작성 해야 하는 걸까? (0) 2020.08.21 - 글로벌 네임스페이스로 노출이 되어 현재 Activity 에서 사용중이지 않은 View 를 참조 할 수 있다.