binding 글 링크
개념-데이터-바인딩data-Binding (1)
개념-데이터-바인딩data-Binding (2)
개념-데이터-바인딩data-Binding (3)
개념-데이터-바인딩data-Binding (4)
개념-데이터-바인딩data-Binding (5)
data binding 라이브러리는 import, Variables 및 Include와 같은 기능을 제공합니다. import를 사용하면 레이아웃 파일 내에서 클래스를 쉽게 참조할 수 있습니다. Variables를 사용하면 결합 표현식에 사용할 수 있는 속성을 설명할 수 있습니다. Include을 사용하면 앱 전체에서 복잡한 레이아웃을 재사용할 수 있습니다.
1. Imports
레이아웃에서 import 를 통해 해당 클래스를 참조 할 수 있습니다. 예를들어 View 클래스를 참조하려면 아래와 같이 import 해서 사용합니다.
<data>
<import type="android.view.View"/>
</data>
그러면 View 클래스를 import 하고 있으므로 View.VISIBLE , View.GONE 을 사용하여 아래와 같은 바인딩 코드를 작성 할 수 있습니다.
<TextView
android:text="@{user.lastName}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="@{user.isAdult ? View.VISIBLE : View.GONE}"/>
정적 필드와 정적 메소드 또한 import 후 사용 할 수 있습니다. 다만 kotlin 에서 사용하기 위해서 companion object 에 선언한 필드 혹은 메소드에 @JvmField 혹은 @JvmStatic Annotation 을 추가 한 후 사용 할 수 있습니다. (정적필드가 primitive type 혹은 string 이면 별도의 annotation 을 추가하지 않고 사용 가능합니다)
//Utils.kt
class Utils {
companion object {
@JvmStatic
fun capitalize(name: String): String {
return name.toUpperCase()
}
}
}
//layout
<data>
<import type="pistolcaffe.databindingexample.Utils"/>
....
</data>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{Utils.capitalize(user.firstName)}" />
만약 import 하려는 class 명이 같다면, 아래와 같이 별도의 alias 를 지정하여 사용 할 수 있습니다.
<import type="android.view.View"/>
<import type="com.example.real.estate.View"
alias="Vista"/>
2. Imports 예제 코드
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="android.view.View"/>
<variable
name="mainactivity"
type="com.project.databindingimport.MainActivity" />
</data>
<LinearLayout
android:orientation="vertical"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="50sp"
android:text="@{mainactivity.text}"
android:visibility='@{mainactivity.isClicked ? View.GONE : View.VISIBLE}' />
<Button
android:id="@+id/hideButton"
android:text="버튼"
android:textSize="50sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</layout>
class MainActivity : AppCompatActivity() {
val text = "Hello World!"
var isClicked = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.mainactivity = this
binding.hideButton.setOnClickListener {
isClicked = !isClicked
binding.invalidateAll()
}
}
}
invalidateAll() 은 바이딩 된 데이터가 변경 됐을 때 UI를 refresh 해줍니다. 바인딩 된 데이터 변경 후 invalidateAll()을 사용해야 합니다.
3. Variables
data 요소 내에서 여러 variable 요소를 사용할 수 있습니다. 각 variable 요소는 레이아웃 파일 내 결합 표현식에 사용될 레이아웃에서 설정할 수 있는 속성을 설명합니다. 다음 예에서는 user, image 및 note 변수를 선언합니다.
<data>
<import type="android.graphics.drawable.Drawable"/>
<variable name="user" type="com.example.User"/>
<variable name="image" type="Drawable"/>
<variable name="note" type="String"/>
</data>
안에 선언되는 variable 은 빌드 시 binding 클래스가 생성 되면서 각각의 setter/getter 메소드를 갖게 됩니다. 이때 setter 가 호출 되기 전 기본 값은 참조 형식의 variable 은 null, int 의 경우 0, boolean 의 경우 false 를 갖습니다.
만약 참조하려는 variable 이 null일 경우 NullpointerException 을 방지 하기 위해 위와 같은 기본 값이 return 됩니다. 예를들어 "@{user.age}" 일 때 user 가 null 인 경우 age(Int) 의 기본 값인 0 이 할당되게 됩니다.
또한 기본적으로 binding 클래스가 생성 될때 root view 의 context 를 가져오게 되는데, 레이아웃 파일에서 "context" 라는 이름으로 context 를 사용 할 수도 있습니다. context 를 사용하여 color resource 를 가져온 뒤 textColor 를 설정해 보겠습니다.
<data>
<import type="android.support.v4.content.ContextCompat"/>
...
</data>
<TextView
android:id="@+id/test1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@{ContextCompat.getColor(context, android.R.color.holo_green_light)}" />
color resource 를 바로 설정해도 되지만 레이아웃 파일에서 context variable 사용 예제를 위해 작성해보았습니다. 변수선언에 있어 유의사항은 가로/세로 모드에 따른 별도의 binding 구현 시 변수이름이 충돌되지 않게 선언하여 사용해야 한다는 점입니다.
4. Include
레이아웃 파일에서 include 태그를 사용 시 include 하려는 레이아웃 파일로 변수를 전달 할 수 있습니다.
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/name"
bind:user="@{user}"/>
<include layout="@layout/contact"
bind:user="@{user}"/>
</LinearLayout>
</layout>
include 한 name.xml 과 contact.xml 에 bind:variable 속성을 통해 user 변수를 전달 하였습니다.
이렇게 사용하기 위해서는 전달 받고자 하는 레이아웃 파일에서 같은 이름의 변수가 선언 되어있어야 합니다
그러나 merge 태그의 하위요소로서 include 를 허용하지 않습니다. 예를들어 다음과 같은 형태는 지원하지 않습니다
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable name="user" type="com.example.User"/>
</data>
<merge>
<include layout="@layout/name"
bind:user="@{user}"/>
<include layout="@layout/contact"
bind:user="@{user}"/>
</merge>
</layout>
https://developer.android.com/topic/libraries/data-binding/start
https://developer.android.com/topic/libraries/data-binding
https://developer.android.com/topic/libraries/data-binding/expressions