반응형
Android Kotlin Fundamentals는 codelab에 올라와있는 강의를 한글로 번역한 내용입니다.
Codelabs for Android Kotlin Fundamentals | Training Courses
Content and code samples on this page are subject to the licenses described in the Content License. Java is a registered trademark of Oracle and/or its affiliates. Last updated 2020-09-14 UTC.
developer.android.com
코드는 github를 참고해주세요
02-4 Data Binding
1. Data binding을 사용하여 findViewById() 제거
- findViewById()를 사용하여 view가 create되고 recreate 된 이후에 리소스를 찾을 때 마다 안드로이드 시스템은 runtime 중에 뷰 계층 구조를 탐색한다.
- 가벼운 앱이라면 상관 없겠지만 상용 앱에서는 레이아웃에 수십가지의 뷰가 있을 수도 있고, 많은 뷰가 중첩되어 있을 수도 있다
- LinearLayout에 ScrollView가 포함되어 있고 그 ScrollView 안에 TextView가 포함되어 있다고 생각해보자. 규모가 크거나 깊은 뷰 계층 구조를 가지고 있으면 뷰를 찾는 데 시간이 오래 걸리고 사용자의 앱 속도가 눈에 띄게 느려질 수도 있다
- 해결책은 각 뷰에 참조가 포함된 객체를 만드는 것이다. 이 객체는 Binding 객체라고도 부르며 전체 앱에서 사용할 수 있다.
- 이 기술을 data binding이라고 하며, 앱에 대한 binding 객체가 생성되면 뷰 계층을 모두 다 훑거나 검색하지 않고도 바인딩 객체를 통해 뷰 및 다른 데이터에 엑세스 할 수 있다.
- 데이터 바인딩의 이점은 다음과 같다
- findViewById()를 사용하는 코드보다 코드가 짧고 읽기 쉽고 유지 관리하기 쉽다
- 데이터와 뷰가 명확하게 분리된다.
- 안드로이드 시스템은 뷰 계층 구조를 한번만 탐색하여 각 뷰를 가져오며 사용자가 앱과 상호작용 하는 runtime 때가 아닌 앱 시작 중에 발생한다
- type safety를 얻을 수 있다. (type safety는 컴파일러가 컴파일 하는 동안 type의 유효성을 검사하고 변수에 잘못된 타입을 할당하려고 하면 오류를 발생시킨다.)
1) 데이터 바인딩 활성화
- data binding을 사용하기 위해서는 Gradle 파일에 데이터 바인딩을 활성화 시켜야 된다.
// build.gradle (Module: app) android { ... dataBinding { enabled = true } }
2) 데이터 바인딩을 사용할 수 있도록 layout 파일 변경
- data binding을 사용하기 위해서는 XML 레이아웃 파일을 <layout></layout>으로 감싸야 한다.
- 루트 클래스는 더이상 ViewGroup이 아닌 view와 view group들을 포함하는 layout이 루트 클래스가 된다.
- layout 태그로 감싸면 바인딩 객체가 레이아웃과 그 안에 있는 뷰에 대해 알 수 있다.
3) main activity에 binding 객체 생성
(1) 액티비티에 binding 객체 참조 추가
// MainActivity.kt
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
}
(2) setContentView() -> DataBindingUtil.setContentView()
- 현재 사용하고 있는 setContentView()를 다음을 수행하는 함수로 변경한다.
- Binding 객체를 생성한다
- DataBindingUtil.setContentView()를 사용하여 activity_main 레이아웃과 MainActivity를 연결시킨다
// MainActivity.kt import androidx.databinding.DataBindingUtil override fun onCreate(savedInstanceState: Bundle?) { // setContentView(R.layout.activity_main) binding = DataBindingUtil.setContentView(this, R.layout_activity_main) }
4) findViewById()를 호출하는 모든 코드를 binding object를 사용하여 변경
- binding 객체가 생성되면 컴파일러는 layout 내에 있는 뷰의 ID로부터 camel case binding 객체의 뷰 네임을 생성한다.로
- 예를 들어 done_button은 doneButton, nickname_edit은 nicknameEdit이 된다.
- (1) findViewById() -> 바인딩 객체에서 button을 참조하는 코드로 변경한다.
- findViewById(R.id.done_button) -> binding.doneButton
// MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout_activity_main)
// findViewById<Button>(R.id.done_button).setOnClickListener {
// addNickname(it)
// }
binding.doneButton.setOnClickListener{
addNickname(it)
}
}
}
2. Use data biding to display data
데이터 바인딩을 활용하여 data class를 뷰에 직접 사용할 수도 있다. 이 기술은 코드를 단순화하며 더 복잡한 경우를 처리하는 데 매우 유용하다
1) Create the MyName data class
- MyName data class 생성
data class MyName(var name: String = "", var nickname: String = "")
2) Add data to the layout
- activity_main.xml을 열어 과 태그 사이에 태그를 추가한다
- 태그 안에 태그를 추가한다
<data>
<variable
name="myName"
type="com.example.kotlin.a02_4_databinding.MyName"/>
</data>
- @={} 은 중괄호 안에서 참조되는 데이터를 가져오는 지시문이다.
- TextView의 text를 android:text="@string/name" 에서 android:text="@={myName.name}"으로 변경한다
3) Create the data
- MainActivity.kt를 열어 onCreate() 위에 private 변수로 myName을 만든다.
- onCreate()에서는 레이아웃 파일의 myName 변수값을 방금 선언한 myName 변수값으로 설정한다.
private val myName: MyName = MyName("Aleks Haecky")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.myName = myName
}
4) Use the data class for the nickname in the TextView
- activity_main.xml을 열어서 nickname_text 텍스트 뷰의 text 프로퍼티를 다음과 같이 변경한다
<TextView
android:id="@+id/name_text"
android:text="@={myName.nickname}"
..
/>
- MainActivity.kt의 nicknameText.text = nicknameEdit.text.toString() 코드를 아래와 같이 변경한다
myName?.nickname = nicknameEdit.text.toString()
- nickname 값이 설정되고 나면 코드에서 새 데이터로 UI를 업데이트 하려고 한다. 이렇게 하려면 올바른 데이터로 다시 recreate 하기 위해 바인딩 표현들을 모두 invalidate 시켜야 된다.
- invalidateAll() : Invalidates all binding expressions and requests a new rebind to refresh UI.
- 수정된 binding 객체로 UI를 갱신하기 위해 nickname 값 설정 후 invalidateAll() 함수를 추가한다.
binding.apply {
myName?.nickname = nicknameEdit.text.toString()
invalidate()
...
}
3. Summary
1) findViewById() 대신 data binding을 사용해라
- build.gradle 파일의 android 영역 내에 dataBinding { enable = true } 추가
- <\layout>을 XML 레이아웃의 root view로 사용한다
- binding 변수를 정의한다
private lateinit var binding: ActivityMainBinding
- setContentView를 아래와 같이 대체하여 binding 객체를 생성한다
bidnding = dataBindingUtil.setContentView(this, R.layout.activity\_main)
- findViewById()에 대한 호출을 binding object의 참조로 사용한다
findViewById<Button>(R.id.done_button) => binding.doneButton
2) 뷰에 데이터 바인딩시키기
- data class를 작성한다
- <layout>태그 안에 <data>태그 블럭을 추가한다
- data class 유형으로 <variable>을 정의한다
<data>
<variable
name="myName"
type="com.example.android.abountMe.myName"/>
</data>
- MainActivity에서 data class의 인스턴스로 변수를 만든다
private val myName: MyName = MyName("Aleks Haeck")
- binding 객체에 변수를 방금 작성한 변수로 설정한다
binding.myName = myName
- XML에서 뷰의 내용을 <data>블록에서 정의한 변수로 설정한다. 점 표기법을 사용하여 data class 내부의 데이터에 접근할 수 있다
android:text="@={myName.name}"
728x90
'android > android kotlin fundamentals' 카테고리의 다른 글
03-2. Navigation (0) | 2021.02.16 |
---|---|
03-1. Fragment (0) | 2021.02.16 |
02-3. Constraint Layout (0) | 2021.02.16 |
02-1. Linear Layout (0) | 2021.02.16 |
01-3. Learn To Help Yourself (0) | 2021.02.16 |
댓글