들어가기 전
Kotlin 1.4.20
Release에서 변경점이 생겼습니다. kotlin extensions plugin이 deprecated 된 점입니다.
kotlin extensions plugin에는 synthetic views라는 뷰에 대해 접근하는 코드를 생략해주던 기능이 포함 되어 있었습니다.
<TextView android:id="@+id/name" />
//Activity or Fragment
name.text = "test"
그런데 새로운 버전에서는 dprecated 되었으니 계속 해당 기능을 이용할 수는 없습니다. 다른 대안이 있을까요?
ViewBinding란?
Android AAC 중 하나로 view의 접근하는 코드를 조금 더 쉽게 작성할 수 있게 도와주는 기능입니다.
ex) findViewByID 대신 사용 할 수 있다.
Gradle 설정
etc. Android Studio 3.6 Canary 11+ 이상 사용가능
- build.gradle에서 모듈 추가
android {
...
buildFeatures {
viewBinding true
}
}
사용방법
<LinearLayout ... >
<TextView android:id="@+id/name" />
<ImageView android:cropToPadding="true" />
<Button android:id="@+id/button"
android:background="@drawable/rounded_button" />
</LinearLayout>
activity_main.xml
이름으로 정의되어 있다면 ViewBinding 모듈로 인해 ActivityAddBinding이라는 binding class가 생성됩니다. 생성되는 binding class는 xml의 이름을 파스칼 표기법으로 변경한 뒤 접미사 Binding을 붙여 결정됩니다.
위 XML로 생성된 binding class는 name이라는 TextView와 button이라는 Button을 필드를 가지고 있습니다. 이는 id가 정의되어 있는 View들을 의미하는 것으로 Id가 정의되어 있지 않은 ImageView는 접근할 수 없습니다.
<LinearLayout
...
tools:viewBindingIgnore="true" >
...
</LinearLayout>
ViewBinding 모듈로 인해 프로젝트에 정의 되어 있는 모든 xml에 binding class가 생성됩니다. 만일 어떤한 뷰는 binding class 생성을 원치 않을 경우 위 속성을 추가합니다.
- Activity에서 binding class 사용하기
private lateinit var binding: ActivityAddBinding
override fun onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
binding = ActivityAddBinding.inflate(layoutInflater)
val view = binding.root //or binding.getRoot()
setContentView(view)
}
- Fragment에서 binding class 사용하기
private var _binding: ActivityAddBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = ActivityAddBinding.inflate(inflater, container, false)
val view = binding.root
return view
}
override fun onDestroyView() {
_binding = null
}
Fragment에서는 onDestroyView
에서 binding을 null 해주어 view의 lifecycle을 직접 관리합니다. Fragment는 Fragment와 Fragment의 View 2개의 Lifecycle이 존재하므로 View가 사라진 시점에서 불필요하게 남아있는 접근하면 안되는 binding class를 지워주는 것이 좋습니다.
- binding class에서 view 접근
binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }
ViewBinding의 이점
- Null-Safe
- findViewById는 매개변수로 넘겨진 resId 값이 뷰 안에 존재하지 않다면 Null을 반환할 수 있어 Null Safe하지 않습니다.
- Type-Safe
참고 - binding class 생성될 시, 자동으로 Type을 맞춰주어 referense를 생성해주기 때문에 (ex) name:TextView, button:Button)
classCaseException이 발생하지 않습니다.
'Android > Common' 카테고리의 다른 글
[Android]SharedPreferences by Kotlin (0) | 2020.03.27 |
---|---|
[Android] 음성 인식 기능 추가하는 방법 정리 (0) | 2020.03.26 |
[Android] 면접에서 헷갈릴수 있는 Activity Lifecycle (0) | 2020.03.05 |
[Android]Keybard Show/Hide 감지하기 (0) | 2020.02.12 |
[Android] RecyclerView의 최상단 최하단 감지하기 (0) | 2020.02.10 |