Android

View Binding, Data Binding (android developers)

 

  1. View Binding
  2. Data Binding Library

 

View Binding
https://developer.android.com/topic/libraries/view-binding#java

 

Data Binding
https://developer.android.com/topic/libraries/data-binding#java

 


  1. View Binding

 

 

모듈 레벨 build.gradle 파일

 

android {
    ...
    buildFeatures {
        viewBinding true
    }
}

 

 

 

바인딩 클래스를 만들지 않으려면 루트 뷰에다가 추가

<LinearLayout
    ...
    tools:viewBindingIgnore="true" >
    ...
</LinearLayout>

 

 

바인딩 클래스 자동 생성 (클래스 이름은 camel case 그리고 뒤에 Binding이 붙음)

result_profile.xml -> ResultProfileBinding

 

<LinearLayout ... >
    <TextView android:id="@+id/name" />
    <ImageView android:cropToPadding="true" />
    <Button android:id="@+id/button"
        android:background="@drawable/rounded_button" />
</LinearLayout>

 

 

 

Use view binding in activities

 

private ResultProfileBinding binding;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ResultProfileBinding.inflate(getLayoutInflater());
    View view = binding.getRoot();
    setContentView(view);
}

the getRoot() method in the ResultProfileBinding class returns the LinearLayout root view.

 

 

binding.getName().setText(viewModel.getName());
binding.button.setOnClickListener(new View.OnClickListener() {
    viewModel.userClicked()
});

 

 

 

 

Use view binding in fragments

 

private ResultProfileBinding binding;

@Override
public View onCreateView (LayoutInflater inflater, 
                          ViewGroup container, 
                          Bundle savedInstanceState) {
    binding = ResultProfileBinding.inflate(inflater, container, false);
    View view = binding.getRoot();
    return view;
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    binding = null;
}

 

Note: Fragments outlive their views. Make sure you clean up any references to the binding class instance in the fragment’s onDestroyView() method.

 

 

binding.getName().setText(viewModel.getName());
binding.button.setOnClickListener(new View.OnClickListener() {
    viewModel.userClicked()
});

 

 

 

 

 

 


 

2. Data Binding Library

 

 

Overview

 

액티비티에서 사용하는 바인딩 방법

TextView textView = findViewById(R.id.sample_text);
textView.setText(viewModel.getUserName());

 

Data Binding Library 를 사용해서 레이아웃 파일에서 직접 바인딩 하는 방법

<TextView
    android:text="@{viewmodel.userName}" />

 

레이아웃에서 바인딩을 하게 되면 액티비티에서의 많은 UI 프레임워크 호출을 없애주고 유지보수가 더 간단하고 쉽게 만든다.
또한 앱의 성능을 향상시켜주고 메모리릭이나 널포인터예외 방지에 도움을 준다.

 

  1. Binding Library 는 자동으로 바인딩에 필요한 클래스를 생성한다.
  2. 세가지의 기능을 제공한다. (imports, variables, and includes)
  3. layout 태그가 최상위, 자식 태그로 data 태그와 루트 뷰
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <variable
            name="viewmodel"
            type="com.myapp.data.ViewModel" />
    </data>
    <ConstraintLayout... /> <!-- UI layout's root element -->
</layout>

 

 

Get started

 

Android 4.0 (API level 14) or higher.

build.gradle file in the app module

android {
    ...
    buildFeatures {
        dataBinding true
    }
}

 

레이아웃 편집기의 미리보기에서 default 값이 표시된다.

<TextView android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@{user.firstName, default=my_default}"/>

 

 

 

Layouts and binding expressions

 

데이터 바인딩 레이아웃 파일은 layout 루트, data 태그, view 루트 태그로 구성된다.

 

<?xml version="1.0" encoding="utf-8"?>
<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}"/>
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.lastName}"/>
   </LinearLayout>
</layout>

 

data 태그에 있는 user 변수는 이 레이아웃에서 사용된다.

<variable name="user" type="com.example.User" />

 

 

문법 @{} 사용
TextView 의 text 는 user 변수의 firstName 프로퍼티로 설정된다.

<TextView android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@{user.firstName}" />

 

 

 

Data object

 

일반 엔티티

public class User {
  public final String firstName;
  public final String lastName;
  public User(String firstName, String lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
  }
}

 

getter, setter 이용 엔티티

public class User {
  private final String firstName;
  private final String lastName;
  public User(String firstName, String lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
  }
  public String getFirstName() {
      return this.firstName;
  }
  public String getLastName() {
      return this.lastName;
  }
}

 

 

Binding data

 

레이아웃 파일들은 바인딩 클래스가 자동으로 생성된다.

activity_main.xml -> ActivityMainBinding

 

추천되는 방식

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
   User user = new User("Test", "User");
   binding.setUser(user);
}

 

LayoutInflater 을 이용하는 방법

ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());

 

 

Fragment, ListView, or RecyclerView adapter 내부에서 데이터바인딩 사용

ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
// or
ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);

 

 

 

Expression language

 

Mathematical + – / * %
String concatenation +
Logical && ||
Binary & | ^
Unary + – ! ~
Shift >> >>> <<
Comparison == > < >= <= (Note that < needs to be escaped as &lt;)
instanceof
Grouping ()
Literals – character, String, numeric, null
Cast
Method calls
Field access
Array access []
Ternary operator ?:

 

android:text="@{String.valueOf(index + 1)}"
android:visibility="@{age > 13 ? View.GONE : View.VISIBLE}"
android:transitionName='@{"image_" + id}'

 

없는 키워드

this
super
new
Explicit generic invocation

 

Null coalescing operator

왼쪽이 null 이 아니면 왼쪽, null 이면 오른쪽

android:text="@{user.displayName ?? user.lastName}"

 

위와 동일

android:text="@{user.displayName != null ? user.displayName : user.lastName}"

 

 

 

Property references

 

fields, getters, and ObservableField objects 에서도 같음

android:text="@{user.lastName}"

 

 

 

Avoiding null pointer exceptions

 

생성된 바인딩 클래스는 자동을 null 체크를 하고 null 포인터 예외를 방지한다.
@{user.name} 에서 user 가 null 이이면 user.name (string)의 디폴트 값인 null 사용
@{user.age} 에서 user 가 null 이면 user.age (int)의 디폴트 값인 0 사용

 

 

 

View references

 

표현식은 ID 로 다른 뷰를 참조할 수 있다.

android:text="@{exampleText.text}"

 

 

바인딩 클래스는 ID 를 camel case 로 컨버팅한다.

<EditText
    android:id="@+id/example_text"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"/>
<TextView
    android:id="@+id/example_output"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@{exampleText.text}"/>  // EditText 뷰의 text 를 참조

 

 

 

Collections

 

arrays, lists, sparse lists, maps 같은 컬렉션들은 [] 연산자를 사용해서 접근할 수 있다.

 

<data>
    <import type="android.util.SparseArray"/>
    <import type="java.util.Map"/>
    <import type="java.util.List"/>
    <variable name="list" type="List&lt;String>"/>
    <variable name="sparse" type="SparseArray&lt;String>"/>
    <variable name="map" type="Map&lt;String, String>"/>
    <variable name="index" type="int"/>
    <variable name="key" type="String"/>
</data>
…
android:text="@{list[index]}"
…
android:text="@{sparse[index]}"
…
android:text="@{map[key]}"

 

map 에서 @{map[key]} 또는 @{map.key} 를 사용할 수 있다.

You can also refer to a value in the map using the object.key notation. For example, @{map[key]} in the example above can be replaced with @{map.key}.

 

 

String literals

 

single quotes 와 double quotes 사용

android:text='@{map["firstName"]}'

 

double quotes 와 back quotes 사용

android:text="@{map[`firstName`]}"

 

 

 

Resources

 

리소스 참조

android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}"

 

파라미터 제공

android:text="@{@string/nameFormat(firstName, lastName)}"
android:text="@{@plurals/banana(bananaCount)}"

 

프로퍼티 레퍼런스와 뷰 레퍼런스를 리소스 파라미터로 제공

android:text="@{@string/example_resource(user.lastName, exampleText.text)}"

 

다수의 파라미터가 필요하다면 모든 파라미터를 제공해야한다.

  Have an orange
  Have %d oranges

android:text="@{@plurals/orange(orangeCount, orangeCount)}"

 

 

 

일부 리소스들은 명시적 타입 평가가 필요

Type Normal reference Expression reference
String[] @array @stringArray
int[] @array @intArray
TypedArray @array @typedArray
Animator @animator @animator
StateListAnimator @animator @stateListAnimator
color int @color @color
ColorStateList @color @colorStateList

 

 

 

 

Event handling

 

Method references: 리스너 메서드 시그니처에 맞는 메서드를 참조한다.
Listener bindings: 이벤트가 발생할 때 평가되는 람다 식.

 

 

 

Method references

 

메소드 핸들러에 직접 바인딩 됨

public class MyHandlers {
    public void onClickFriend(View view) { ... }
}

 

 

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
   <data>
       <variable name="handlers" type="com.example.MyHandlers"/>
       <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:onClick="@{handlers::onClickFriend}"/>
   </LinearLayout>
</layout>

 

 

 

Listener bindings

 

이벤트가 발생될 때 표현식이 실행

리턴값만 일치하면 된다.

 

public class Presenter {
    public void onSaveClick(Task task){}
}

 

 

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="task" type="com.android.example.Task" />
        <variable name="presenter" type="com.android.example.Presenter" />
    </data>
    <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent">
        <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:onClick="@{() -> presenter.onSaveClick(task)}" />
    </LinearLayout>
</layout>

 

you still get null and thread safety of data binding

 

파라미터를 생략할 수도 있고 모두 적을 수도 있다.
아래 예에서는 view 파라미터를 지정하고 있다.

android:onClick="@{(view) -> presenter.onSaveClick(task)}"

 

 

위의 예에서 View 파라미터를 지정했을 때.

public class Presenter {
    public void onSaveClick(View view, Task task){}
}

 

 

<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content"
      android:onCheckedChanged="@{(cb, isChecked) -> presenter.completeChanged(task, isChecked)}" />

 

 

android:onClick="@{(theView) -> presenter.onSaveClick(theView, task)}"

 

 

두 개 이상의 파라미터를 사용한 람다 식

public class Presenter {
    public void onCompletedChanged(Task task, boolean completed){}
}

 

 

<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content"
      android:onCheckedChanged="@{(cb, isChecked) -> presenter.completeChanged(task, isChecked)}" />

 

 

리턴 값이 존재 할 경우

public class Presenter {
    public boolean onLongClick(View view, Task task) { }
}

 

onLongClick 는 boolean 값을 리턴한다.

android:onLongClick="@{(theView) -> presenter.onLongClick(theView, task)}"

 

표현식을 null 로 평가된다면 그 타입의 기본 값이 사용된다. 레퍼런스 타입은 null, int 형은 0, boolean 은 false.

삼항 연산자 (ternary) 에서 사용할 때 void 를 사용할 수 있다.

android:onClick="@{(v) -> v.isVisible() ? doSomething() : void}"

 

 

 

Imports, variables, and includes

 

Imports 는 레이아웃 파일 내부에서 클래스 참조를 쉽게 해준다.
Variables 는 바인딩 표현식에서 프로퍼티를 사용할 수 있다.
Includes 는 앱에서 복잡한 레이아웃을 재사용할 수 있다.

 

 

Imports

 

레이아웃 파일에서 클래스 참조를 가능하게 해준다.

<data>
    <import type="android.view.View"/>
</data>

 

View 클래스의 VISIBLE 과 GONE 상수를 참조한다.

<TextView
   android:text="@{user.lastName}"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:visibility="@{user.isAdult ? View.VISIBLE : View.GONE}"/>

 

 

Type aliases

이름 충돌이 있을 때 별칭을 부여할 수 있다.

<import type="android.view.View"/>
<import type="com.example.real.estate.View"
        alias="Vista"/>

 

 

Import other classes

 

임포트된 타입들은 variables 와 expressions 에서 타입 참조로 사용할 수 있다.

다음 예제는 변수 참조로 User 와 List<User> 을 사용한다.

<data>
    <import type="com.example.User"/>
    <import type="java.util.List"/>
    <variable name="user" type="User"/>
    <variable name="userList" type="List&lt;User>"/>
</data>

 

# IDE 에서 임포트에 대해서 자동완성이 안되므로 풀 네임을 적어주어야 한다.

 

표현식의 일부를 캐스팅하기 위해서 타입 참조를 할 수 있다.

다음 예제는 user.connection 프로퍼티를 User 타입으로 캐스팅한다.

 

<TextView
   android:text="@{((User)(user.connection)).lastName}"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>

 

 

임포트된 타입은 표현식에서 static 필드와 메소드를 참조하는데 사용할 수 있다.

다음 코드는 MyStringUtils 클래스를 임포트하고 capitalize method 를 참조한다.

<data>
    <import type="com.example.MyStringUtils"/>
    <variable name="user" type="com.example.User"/>
</data><TextView
   android:text="@{MyStringUtils.capitalize(user.lastName)}"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>

 

java.lang.* 자동으로 임포트된다.

 

 

Variables

 

data 엘리먼트 안에 여러개의 variable 를 가질 수 있다.

<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>

 

context 의 값은 루트뷰의 getContext() 메서드의 Context 객체이다.

 

 

Includes

 

Variable 은 상위 레이아웃에서 포함된 레이아웃에 전달될 수 있다. app 네임스페이스와 변수 이름을 사용해서

 

<?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>

 

 

데이터 바인딩은 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><!-- Doesn't work -->
       <include layout="@layout/name"
           bind:user="@{user}"/>
       <include layout="@layout/contact"
           bind:user="@{user}"/>
   </merge>
</layout>

 

 

 

Work with observable data objects

 

 

 

Observable fields

 

ObservableBoolean
ObservableByte
ObservableChar
ObservableShort
ObservableInt
ObservableLong
ObservableFloat
ObservableDouble
ObservableParcelable

 

 

private static class User {
    public final ObservableField<String> firstName = new ObservableField<>();
    public final ObservableField<String> lastName = new ObservableField<>();
    public final ObservableInt age = new ObservableInt();
}

 

 

user.firstName.set("Google");
int age = user.age.get();

 

 

Observable collections

 

ObservableArrayMap 클래스는 키가 String 처럼 레퍼런스 타입일 때 유용하다.

 

ObservableArrayMap<String, Object> user = new ObservableArrayMap<>();
user.put("firstName", "Google");
user.put("lastName", "Inc.");
user.put("age", 17);

 

 

<data>
    <import type="android.databinding.ObservableMap"/>
    <variable name="user" type="ObservableMap<String, Object>"/>
</data><TextView
    android:text="@{user.lastName}"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
<TextView
    android:text="@{String.valueOf(1 + (Integer)user.age)}"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

 

 

ObservableArrayList 클래스는 키가 정수형일 때 유용하다.

 

ObservableArrayList<Object> user = new ObservableArrayList<>();
user.add("Google");
user.add("Inc.");
user.add(17);

 

<data>
    <import type="android.databinding.ObservableList"/>
    <import type="com.example.my.app.Fields"/>
    <variable name="user" type="ObservableList<Object>"/>
</data><TextView
    android:text='@{user[Fields.LAST_NAME]}'
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
<TextView
    android:text='@{String.valueOf(1 + (Integer)user[Fields.AGE])}'
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

 

 

Observable objects

 

Data Binding 라이브러리는 리스너 등록 메커니즘을 등록하는 BaseObservable 클래스를 제공한다.
게터와 세터에 Bindable annotation 을 설정하고 세터의 notifyPropertyChanged() 메서드를 호출한다.

 

private static class User extends BaseObservable {
    private String firstName;
    private String lastName;

    @Bindable
    public String getFirstName() {
        return this.firstName;
    }

    @Bindable
    public String getLastName() {
        return this.lastName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
        notifyPropertyChanged(BR.firstName);
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
        notifyPropertyChanged(BR.lastName);
    }
}

 

데이터 바인딩은 모듈 패키지에 BR 클래스를 생성한다. 데이터 바인딩에 사용되는 리소스 ID 를 포함한다.
컴파일 타임에 Bindable annotation 은 BR 클래스 파일에 항목을 생성한다.
베이스 클래스를 변경할 수 없다면 PropertyChangeRegistry 객체를 사용한다.

 

 

Generated binding classes

 

각 레이아웃 파일에 대해서 바인딩 클래스가 생성된다.
기본적으로 바인딩되는 클래스 이름은 레이아웃 파일 이름에 기반을 둔다. Pascal case, Binding suffix
activity_main.xml -> ActivityMainBinding

 

 

Create a binding object

 

바인딩 객체는 레이아웃을 인플레이트 직 후에 만들어진다.
바인딩 객체와 레이아웃을 바인딩하는 하는 가장 일반적인 방법은 static 메서드를 사용하는 것이다.
바인딩 클래스의 inflate() 메서드를 사용해서 뷰 계층을 인플레이트하고 바인딩 객체에 바인딩한다.

 

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater());

    setContentView(binding.root);
}

 

 

LayoutInflater 객체와 ViewGroup 객체를 가지는 inflate() 메서드의 또 다른 버전이 있다.

 

MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false);

 

레이아웃이 다른 메커니즘을 사용해서 이미 인플레이트 되었다면 따로 바인딩될 수 있다.

 

MyLayoutBinding binding = MyLayoutBinding.bind(viewRoot);

 

때때로 바인딩 타입이 미리 알 수 었을 경우에 DataBindingUtil 클래스를 사용해서 바인딩 할 수 있다.

 

View viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent);
ViewDataBinding binding = DataBindingUtil.bind(viewRoot);

 

Fragment, ListView, 또는 RecyclerView adapter 내부에서 데이터 바인딩 아이템을 사용한다면 바인딩 클래스의 inflate() 메서드나 DataBindingUtil 클래스를 사용을 선호할 수 있다.

 

ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
// or
ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);

 

 

Views with IDs

 

데이터 바인딩 라이브러리는 레이아웃에서 ID를 가진 각 뷰에 대해서 바인딩 클래스에 immutable 필드를 만든다.
다음 예제에서 데이터 바인딩 라이브러리는 타입 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

 

데이터 바인딩 라이브러리는 레이아웃에 선언된 각 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 에 대해서 접근자 메서드를 생성한다.
다음 레이아웃은 user, image, note 변수에 대해서 바인딩 클래스에 게터 세터 메서드를 생성한다.

 

 

Custom binding class names

 

기본적은 바인딩 클래스는 레이아웃 파일의 이름에 기반을 둔다.
이 클래스는 모듈 패키지의 databinding 패키지에 놓인다.
contact_item -> ContactItemBinding
모듈 패키지가 com.example.my.app 이라면 바인딩 클래스는 com.example.my.app.databinding 패키지에 놓인다.

바인딩 클래스는 data 엘리먼트의 class 어트리뷰트를 변경함으로써 이름 변경이나 다른 패키지에 놓일 수 있다.
다음 예제는 현재 모듈의 databinding 패키지에 ContactItem 바인딩 클래스를 생성한다.

 

<data class="ContactItem">
    …
</data>

 

 

class 엘리먼트에서 점(peroid)을 앞에 붙여서 다른 패키지에 생성한다.
다음 예제는 모듈 패키지에 바인딩 클래스를 생성한다.

 

<data class=".ContactItem">
    …
</data>

 

전체 패키지 이름을 사용해서 바인딩 클래스가 생성될 위치를 지정할 수 있다.
다음 예제는 com.example 패키지에 ContactItem 바인딩 클래스를 생성한다.

 

<data class="com.example.ContactItem">
    …
</data>

 

 

 

 

Related posts

Leave a Comment