일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- binding
- LifeCycle
- textfield
- Flutter
- Navigation
- tabbar
- Button
- data
- CustomScrollView
- intent
- livedata
- scroll
- viewmodel
- 앱
- textview
- appbar
- Coroutines
- ScrollView
- TEST
- Compose
- Kotlin
- 계측
- activity
- 앱바
- drift
- Dialog
- android
- 테스트
- DART
- 안드로이드
- Today
- Total
Study Record
[안드로이드] 데이터 바인딩(Data binding)과 뷰 바인딩(View binding) 본문
😶 findViewById() vs Data binding
View에 대한 접근을 얻기 위해 사용하는 함수인 findViewById()를 사용할 수 있다.
val textView = findViewById<TextView>(R.id.name_tv)
findViewById() 함수가 작동되는 방식은 런타임 때 뷰 계층구조를 훑으면서 인자로 받은 id 값으로 알맞은 View를 찾아서 리턴해준다. 하나의 View를 연결할 때마다 findViewById() 함수를 사용하기 때문에 접근하려는 View 가 많아질수록 비용이 많이 든다.
또한, View 가 많지 않은 간단한 앱에서는 문제가 없지만 View 의 개수가 많아지고 계층 구조가 더 깊어지면 알맞은 View를 찾는데 시간이 오래 걸려 사용자의 앱 속도가 현저히 느려질 수 있다.
이런 findViewById() 의 문제점을 해결하는 하나의 해결책으로 View에 대한 접근을 포함한 객체를 만드는 것이다. 이 객체를 Binding이라고 부르며 앱 전체에서 사용할 수 있다. 이 binding 객에게 한번 앱에서 만들어지면 View와 다른 data를 View 계층구조를 훑지 않고 바로 binding 객체로 접근할 수 있다. 이 기술을 Data Binding이라고 부른다!
🙄 Data Binding 이점
- findViewById() 를 사용할 때보다 코드가 더 간결하고 읽기 쉽고, 유지 관리하기 쉬워진다.
- data와 View를 분리할 수 있다.
- 런타임 때 앱과 상호작용하는 과정에서 안드로이드 시스템이 View 계층구조를 탐색할 필요가 없어진다.
- View에 접근할 때 데이터 타입을 실수할 일이 없어진다. (type safety) - ex. TextView, EditText 등
😶 Data Binding 사용하기
build.gradle(Moudle: [App Name]) 파일에 데이터 바인딩을 사용한다고 선언한다.
android {
...
buildFeatures {
dataBinding true
}
}
sync now 버튼을 누른 뒤, 필요하다면 File > Sync Project with Gradles files를 누른다.
이제 xml 파일에 제일 상위에 <layout> 태그로 감싸준다. 데이터가 있다면 <data> 태그와 <variable> 태그를 이용해 현재 레이아웃에서 사용할 데이터들의 클래스 타입을 선언해 준다.
다음 예시는 name과 nickname 텍스트 뷰와 name 버튼으로 이루어져 있는 화면인데, name 버튼을 누르면 name 과 nickname을 표시해 주는 간단한 기능을 가지고 있다.
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="myInfo"
type="com.example.basic_text.MyName" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp"
tools:context=".MainActivity">
<TextView
android:id="@+id/name_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@={myInfo.name}"
android:textColor="@color/black"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/nickname_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="@={myInfo.nickName}"
android:textColor="@color/black"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/name_tv" />
<Button
android:id="@+id/name_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="Name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/nickname_tv" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
- MyName 데이터 클래스
package com.example.basic_text
data class MyName(
var name: String = "",
var nickName: String = ""
)
예시에서 알 수 있듯 현재 레이아웃에서 사용할 데이터 이름(myInfo)을 적용할 TextView의 text에 @={myInfo.name}과 같은 형식으로 적용해 준다.
Activity에서 binding 객체를 선언하고 setContentView(R.layout.activity_main) 함수를 binding = DataBindingUitl.setContentView(this, R.layout.activity_main) 함수로 선언해 준다.
생성된 binding 객체의 이름은 레이아웃 파일 이름을 기반으로 하여 파스칼 표기법으로 변환하고 Binding 접미사를 추가한다. 따라서 activity_main.xml 에서 생성되는 클래스는 ActivityMainBinding이다.
class MainActivity : AppCompatActivity() {
private lateinit var binding : ActivityMainBinding
private val myName: MyName = MyName("Aleks Heaecky", "Android")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.nameBtn.setOnClickListener {
setName()
}
}
private fun setName() {
binding.myInfo = myName
// binding.invalidateAll()
}
}
binding 객체로 View와 미리 설정한 data에 접근할 수 있는데 View 는 id 값으로 접근한다. id 가 name_btn 이라면 "_" 는 다음 오는 글자를 대문자로 인식해주므로 binding.nameBtn 으로 접근할 수 있다.
binding 객체에 미리 설정한 data 에 접근할 수 있는데 이름을 myInfo로 했다면 binding.myInfo로 가져올 수 있다.
<data>
<variable
name="myInfo"
type="com.example.basic_text.MyName" />
</data>
myInfo는 name과 nickname 텍스트뷰와 서로 연결되어 있으므로 binding.myInfo 의 값만 변경해주면 자동으로 name 과 nickname 텍스트 뷰의 텍스트 값이 변경된다!
- binding.invalidateAll() 함수는 binding 객체가 업데이트된 값으로 UI를 refresh 할 수 있다.
😶 뷰 바인딩(View Binding)
View Binding 도 data Binding과 비슷하게 findViewById()를 대체하는 개념으로 View 데이터를 Binding 객체로 접근할 수 있다. 하지만 data에 대해서는 지원하지 않는다.
😶 뷰 바인딩 사용방법
먼저 gradle 파일 viewBinding을 true로 한다.
android {
...
buildFeatures {
viewBinding = true
}
}
생성된 Binding 객체의 이름은 Data Binding과 마찬가지로 레이아웃 파일 이름을 기반으로 하여 파스칼 표기법으로 변환하고 Binding 접미사를 추가한다. 만약 xml 파일의 이름이 activity_main.xml이라면 Binding 객체 이름은 ActivityMainBinding이다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.textView.text = "textView Example"
}
}
setcontentView 함수로 선언한 binding 객체로 View를 생성하고 접근할 수 있다.
'안드로이드' 카테고리의 다른 글
[안드로이드] Navigation (탐색) 살펴보기 (0) | 2023.06.25 |
---|---|
[안드로이드] Fragment 살펴보기 (0) | 2023.06.22 |
[안드로이드] ConstraintLayout 살펴보기 (0) | 2023.06.17 |
[안드로이드] 키보드 내리기/올리기/Activity 시작 시 자동으로 올리기 (0) | 2023.06.16 |
[안드로이드] EditText 살펴보기 (0) | 2023.06.16 |