티스토리 뷰
데이터 바인딩
뷰 바인딩과 동일하게 findViewById() 호출을 대체할 수 있도록 안드로이드가 지원하는 라이브러리다.
뷰 바인딩과 다른 점은, 액티비티의 데이터와 레이아웃(xml)의 뷰가 바인딩 될 수 있다는 것이다.
즉, 액티비티의 데이터가 변경되면 ui상의 뷰가 자동으로 변경되는 기능을 제공한다.
이를 액티비티 코드 내에서 구현하는 것이 아닌, xml 코드 내에서 구현할 수 있어 코드량이 줄어든다. (declarative 레이아웃 작성)
또한 xml 파일만 보고도 View에 어떤 데이터가 들어가는지 파악할 수 있기 때문에 가독성이 좋아진다.
1. build.gradle (module)
android {
dataBinding {
enabled = true
}
}
module/app 수준의 빌드 파일에 데이터 바인딩 dependency를 추가하고 Build Sync를 누른다.
2. activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="activity"
type=com.example.project.MainActivity" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="{activity.text}"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
이 예제에서는 activity_main.xml이 레이아웃 파일, MainActivity.kt가 코틀린 파일이다.
데이터 바인딩을 사용할 xml에서는 루트 뷰가 layout이어야 한다.
<data>
<variable
name="activity"
type=com.example.project.MainActivity" />
</data>
액티비티의 변수나 객체를 사용하려면
<data></data> 안에 해당하는 액티비티의 이름(별칭)을 name 속성에 정해주고,
type에는 액티비티의 경로를 적는다.
android:text="{activity.text}"
TextView의 text를 데이터 바인딩하기 위해서는 위와 같이 적는다. "@{}"
activity에는 text라는 변수나 객체가 있어야 한다.
activity 내에서 text가 변경되면 TextView의 text도 자동으로 변경된다.
3. MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private var text = "TEXT"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.activity = this
}
}
데이터 바인딩 dependency를 추가하면 xml 파일에 대한 Binding 객체가 생성된다.
이 Binding 객체를 통해서 xml id에 바로 접근하여 뷰를 참조할 수 있다.
Binding 객체의 이름은 "xml 파일의 카멜 표기법" + "Binding" 이다.
(ex: activity_main.xml -> ActivityMainBinding)
이 액티비티 코드에서 text 변수를 변경시키면, ui 상에서도 TextView가 변경될 것이다. (ex: 버튼을 누를 때마다 text 변경)
setContentView(R.layout.activity_main)
그리고 레이아웃 바인딩을 위한 setContentView() 호출의 기존 방식은 위와 같았다.
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
또한 뷰 바인딩에서는 이렇게 호출했다.
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
하지만 데이터 바인딩에서는 위와 같은 방식으로 전달한다.
binding.activity = this
xml에서 액티비티를 가리키는 name(별칭 같은 것)을 activity로 지정했다.
이 activity를 코틀린 파일에서도 대입시켜서 xml과 코틀린 코드 상의 variable을 일치시켜야 한다.
기존 방식과의 비교
<?xml version="1.0" encoding="utf-8"?>
<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">
<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="activity"
type=com.example.project.MainActivity" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="{activity.text}"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
(위에가 기존(findViewById), 아래가 데이터 바인딩)
xml 파일에서는
1. 루트 뷰가 layout
2. <data> 태그 안에 name, type
3. 바인딩하려는 뷰 안에 {@} 구문 추가
setContentView(R.layout.activity_main)
textView = findViewById(R.id.text_view)
textView.setText("TEXT")
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.activity = this
text = "TEXT"
(위에가 기존(findViewById), 아래가 데이터 바인딩)
액티비티 파일에서는
1. binding 객체 생성
2. 뷰 접근시 findViewById 없이 binding 객체를 통해 id에 접근
3. 데이터 바인딩에 사용하는 변수/객체를 바로 변경
예제에서는 간단하게 TextView로만 데이터 바인딩을 사용했지만,
ViewModel이나 RecyclerView를 사용하면 더 효율적일 것이다.
참고
https://developer.android.com/topic/libraries/data-binding?hl=ko
'app > android' 카테고리의 다른 글
[안드로이드/코틀린] Activity와 Fragment 간 데이터 전달하기 (0) | 2023.09.21 |
---|---|
[안드로이드/코틀린] 커스텀 다이얼로그 구현 방법 두 가지 (0) | 2023.09.21 |
[안드로이드/코틀린] RecyclerView 개념 알아보고 구현하기! (0) | 2023.09.21 |
[안드로이드/android] FragmentDialog, CustomDialog match_parent가 안되는 경우 (0) | 2023.09.20 |
[안드로이드/android] Inheritance from an interface with '@JvmDefault' members is only allowed with -Xjvm-default option 에러 (0) | 2023.09.20 |