데이터 결합 라이브러리는 레이아웃의 변수와 뷰에 액세스하는 데 사용할 수 있는 결합 클래스를 생성합니다. 이 문서에서는 생성된 결합 클래스를 만들고 맞춤설정하는 방법을 설명합니다.
생성된 결합 클래스는 레이아웃 변수를 레이아웃 내의 뷰와 연결합니다. 결합의 이름과 패키지를 맞춤설정할 수 있습니다. 생성된 결합 클래스는 모두 ViewDataBinding
클래스에서 상속받습니다.
각 레이아웃 파일의 결합 클래스가 생성됩니다. 기본적으로 클래스 이름은 파스칼 표기법으로 변환된 레이아웃 파일의 이름이며 Binding 접미사가 추가됩니다. 예를 들어 레이아웃 파일 이름이 activity_main.xml
이면 이에 상응하는 생성된 클래스는 ActivityMainBinding
입니다.
이 클래스는 레이아웃 속성에서 레이아웃 뷰까지 모든 결합을 보유하며 결합 표현식의 값을 할당하는 방법을 알고 있습니다.
결합 객체 만들기
결합 객체는 레이아웃을 확장한 직후에 생성되어 뷰 계층 구조가 레이아웃 내의 표현식을 사용하여 뷰에 결합되기 전에 수정되지 않도록 합니다. 객체를 레이아웃에 결합하는 가장 일반적인 방법은 결합 클래스에서 정적 메서드를 사용하는 것입니다. 다음 예와 같이 결합 클래스의 inflate()
메서드를 사용하여 뷰 계층 구조를 확장하고 객체를 여기에 결합할 수 있습니다.
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val binding: MyLayoutBinding = MyLayoutBinding.inflate(layoutInflater) setContentView(binding.root) }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater()); setContentView(binding.root); }
다음 예와 같이 LayoutInflater
객체 외에도 ViewGroup
객체를 사용하는 inflate()
메서드의 대체 버전이 있습니다.
Kotlin
val binding: MyLayoutBinding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false)
Java
MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false);
레이아웃이 다른 메커니즘을 사용하여 확장되는 경우 다음과 같이 별도로 결합할 수 있습니다.
Kotlin
val binding: MyLayoutBinding = MyLayoutBinding.bind(viewRoot)
Java
MyLayoutBinding binding = MyLayoutBinding.bind(viewRoot);
결합 유형을 미리 모를 때도 있습니다. 이러한 경우 다음 코드 스니펫과 같이 DataBindingUtil
클래스를 사용하여 결합을 만들 수 있습니다.
Kotlin
val viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent) val binding: ViewDataBinding? = DataBindingUtil.bind(viewRoot)
Java
View viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent); ViewDataBinding binding = DataBindingUtil.bind(viewRoot);
Fragment
, ListView
또는 RecyclerView
어댑터 내에서 데이터 결합 항목을 사용 중인 경우 다음 코드 예와 같이 결합 클래스 또는 DataBindingUtil
클래스의 inflate()
메서드를 사용하는 것이 좋을 수 있습니다.
Kotlin
val listItemBinding = ListItemBinding.inflate(layoutInflater, viewGroup, false) // or val listItemBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false)
Java
ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false); // or ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);
ID가 있는 뷰
데이터 결합 라이브러리는 레이아웃에 ID가 있는 각 뷰의 결합 클래스에 변경할 수 없는 필드를 만듭니다. 예를 들어 데이터 결합 라이브러리는 다음 레이아웃에서 TextView
유형의 firstName
및 lastName
필드를 만듭니다.
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"
android:id="@+id/firstName"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.lastName}"
android:id="@+id/lastName"/>
</LinearLayout>
</layout>
라이브러리는 단일 패스의 뷰 계층 구조에서 ID가 포함된 뷰를 추출합니다. 이 메커니즘은 레이아웃의 모든 뷰에 findViewById()
메서드를 호출하는 것보다 빠를 수 있습니다.
ID는 데이터 결합이 없을 때만큼 필요하지는 않지만 코드에서 뷰에 액세스해야 하는 경우가 있습니다.
Variables
데이터 결합 라이브러리는 레이아웃에 선언된 각 변수의 접근자 메서드를 생성합니다. 예를 들어 다음 레이아웃은 user
, image
, note
변수의 결합 클래스에 setter 메서드와 getter 메서드를 생성합니다.
<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>
ViewStub
일반 뷰와 달리 ViewStub
객체는 보이지 않는 뷰로 시작됩니다. 객체가 표시되거나 명시적으로 확장되면 다른 레이아웃을 확장하여 레이아웃에서 자신을 대체합니다.
ViewStub
가 뷰 계층 구조에서 사라지므로 결합 객체의 뷰도 사라져 가비지 컬렉션에서 뷰를 요청할 수 있어야 합니다.
뷰는 최종적이므로 ViewStubProxy
객체가 생성된 결합 클래스에서 ViewStub
를 대신하며, 개발자는 ViewStub
가 존재하면 이에 액세스할 수 있고 ViewStub
가 확장될 때 확장된 뷰 계층 구조에 액세스할 수 있습니다.
다른 레이아웃을 확장할 때는 새 레이아웃을 위해 바인딩을 설정해야 합니다.
따라서 ViewStubProxy
는 ViewStub
OnInflateListener
를 수신 대기하고 필요할 때 결합을 설정해야 합니다. 한 번에 하나의 리스너만 존재할 수 있으므로 ViewStubProxy
를 사용하면 결합을 설정한 후 호출하는 OnInflateListener
를 설정할 수 있습니다.
즉시 결합
변수 또는 관찰 가능한 객체가 변경되면 결합은 다음 프레임 이전에 변경되도록 예약됩니다. 그러나 결합을 즉시 실행해야 하는 경우도 있습니다. 강제로 실행하려면 executePendingBindings()
메서드를 사용합니다.
동적 변수
특정 결합 클래스를 알 수 없는 경우도 있습니다. 예를 들어 임의의 레이아웃에서 작동하는 RecyclerView.Adapter
는 특정 결합 클래스를 알지 못합니다. onBindViewHolder()
메서드를 호출하는 동안 결합 값을 할당해야 합니다.
다음 예에서는 RecyclerView
가 결합되는 모든 레이아웃에 item
변수가 있습니다. BindingHolder
객체에는 ViewDataBinding
기본 클래스를 반환하는 getBinding()
메서드가 있습니다.
Kotlin
override fun onBindViewHolder(holder: BindingHolder, position: Int) { item: T = items.get(position) holder.binding.setVariable(BR.item, item); holder.binding.executePendingBindings(); }
Java
public void onBindViewHolder(BindingHolder holder, int position) { final T item = items.get(position); holder.getBinding().setVariable(BR.item, item); holder.getBinding().executePendingBindings(); }
백그라운드 스레드
데이터 모델이 컬렉션이 아닌 한 백그라운드 스레드에서 데이터 모델을 변경할 수 있습니다. 데이터 결합은 평가 중에 각 변수나 필드를 현지화하여 동시 실행 문제를 방지합니다.
맞춤 결합 클래스 이름
기본적으로 결합 클래스는 레이아웃 파일의 이름을 기반으로 생성되어 대문자로 시작하고 밑줄 ( _)을 삭제하고 다음 문자를 대문자로 표기하며 Binding이라는 단어를 접미사로 추가하는 방식으로 생성됩니다. 예를 들어 레이아웃 파일 contact_item.xml
는 ContactItemBinding
클래스를 생성합니다. 클래스는 모듈 패키지 아래의 databinding
패키지에 배치됩니다. 예를 들어 모듈 패키지가 com.example.my.app
이면 결합 클래스는 com.example.my.app.databinding
패키지에 배치됩니다.
data
요소의 class
속성을 조정하여 결합 클래스의 이름을 바꾸거나 결합 클래스를 다른 패키지에 배치할 수 있습니다. 예를 들어 다음 레이아웃은 현재 모듈의 databinding
패키지에 ContactItem
결합 클래스를 생성합니다.
<data class="ContactItem">
...
</data>
클래스 이름 앞에 마침표를 붙이면 다른 패키지의 결합 클래스를 생성할 수 있습니다. 다음 예에서는 모듈 패키지에 결합 클래스를 생성합니다.
<data class=".ContactItem">
...
</data>
결합 클래스를 생성할 전체 패키지 이름을 사용할 수도 있습니다. 다음 예에서는 com.example
패키지에 ContactItem
결합 클래스를 만듭니다.
<data class="com.example.ContactItem">
...
</data>
추가 리소스
데이터 결합에 관한 자세한 내용은 다음 추가 리소스를 참고하세요.
추천 서비스
- 참고: JavaScript가 사용 중지되어 있으면 링크 텍스트가 표시됩니다.
- 레이아웃 및 바인딩 표현식
- 데이터 결합 라이브러리
- 뷰 결합