Data Binding과 ButterKnife, 안드로이드를 처음 접하는 사람에겐 생소한 이름일 것이다. Data Binding과 ButterKnife 안드로이드에서 데이터 바인딩를 도와주는 library이다. 안드로이드에서 데이터 바인딩이란 무엇일까? 바로 UI와 데이터간을 서로 연결하는 프로세스이다. 그렇다면 왜 이러한 라이브러리를 사용하는 것일까? 아래 라이브러리를 사용하지 않았을 때와 그렇지 않을 때의 차이점을 간단하게 살펴보자.
데이터 바인딩을 사용하지 않았을 경우 라이브러리를 사용하지 않았을 때의 코드를 살펴보자. 아래 예시는 안드로이드에 처음 접할 때 만들었던 소스 중 일부를 첨부한다. source
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
32
33
34
35
36
37
38
39
40
// xml 소스 중 일부
<RelativeLayout
android:layout_width ="match_parent"
android:layout_height ="0px"
android:layout_weight ="38"
android:background ="#8B4513"
android:orientation ="vertical"
android:paddingBottom ="2dp"
android:paddingLeft ="16dp"
android:paddingRight ="16dp"
android:paddingTop ="2dp" >
<Button
android:id ="@+id/btn_add"
android:layout_width ="wrap_content"
android:layout_height ="wrap_content"
android:layout_alignParentStart ="true"
android:layout_centerVertical ="true"
android:layout_marginLeft ="4dp"
android:text ="Add"
android:textStyle ="bold" />
<Button
android:id ="@+id/btn_del"
android:layout_width ="wrap_content"
android:layout_height ="wrap_content"
android:layout_alignParentEnd ="true"
android:layout_centerVertical ="true"
android:layout_marginRight ="4dp"
android:text ="Del"
android:textStyle ="bold" />
<TextView
android:layout_width ="wrap_content"
android:layout_height ="wrap_content"
android:layout_centerHorizontal ="true"
android:layout_centerVertical ="true"
android:text ="Select Coffee"
android:textSize ="18dp"
android:textStyle ="bold" />
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
// activity 소스 중 일부
Button btnReset;
Button btnAdd;
Button btnDel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
set ContentView(R.layout.your_view);
btnReset = findViewById(R.id.btn_reset);
btnAdd = findViewById(R.id.btn_add);
btnDel = findViewById(R.id.btn_del);
btnReset.setOnClickListener(mClickListener);
btnAdd.setOnClickListener(mClickListener);
btnDel.setOnClickListener(mClickListener);
}
Button.OnClickListener mClickListener = new View.OnClickListener () {
@Override
public void onClick(View v) {
//pass
}
};
소스를 보기만 해도 답답하다. class 내부에서 변수를 선언해주고 id를 가져와서 연결해주고 listener를 연결한다. 하나의 element마다 3줄을 써야되는 것이다. 그렇다면 이와 같은 것을 제거하기 위해 라이브러리를 사용한다면 어떻게 될까?
- -
ButterKnife를 사용하였을 경우 이 글의 작성 시점 2017-05-11 에는 버터나이프보다 Data Binding이 좀 더 좋은 평을 얻고있다. android 자체적으로 지원하는 라이브러리에 Data Binding이 추가되어 있는 상태이다.
ButterKnife로 소스를 간결하게 하는 법을 소개한다. 사용하는 소스는 ButterKnife 공식 홈페이지 ButterKnife 을 참고하자.
1. gradle setting
app의 build.gradle에 다음 소스를 추가한다. 우리가 주목해야 하는 부분은 아래와 같다.
apply plugin: ‘android-apt’ compile ‘com.jakewharton:butterknife:8.5.1’ apt ‘com.jakewharton:butterknife-compiler:8.5.1’ testCompile ‘junit:junit:4.12’
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// app\build.gradle 중 일부
apply plugin: 'android-apt'
dependencies {
compile fileTree(dir: 'libs' , include: ['*.jar' ])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2' , {
exclude group: 'com.android.support' , module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.jakewharton:butterknife:8.5.1'
apt 'com.jakewharton:butterknife-compiler:8.5.1'
test Compile 'junit:junit:4.12'
}
project의 build.gradle에 다음 소스를 추가한다. 우리가 주목해야 할 부분은 아래와 같다.
classpath ‘com.neenbedankt.gradle.plugins:android-apt:1.8’
1
2
3
4
5
6
7
8
9
10
11
12
13
// build.gradle 중 일부
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.1'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
2. example 아래 소스를 보면 ButterKnife.bind(this); 라는 부분에서 지금 사용하는 Activity의 layout(xml)에 해당하는 부분을 바인딩하고 @BindView에서 id를 연결해 주는 모습이다. 이는 class 내부에서 사용할 때 변수 선언을 해주고 안드로이드의 생명 주기상 onCreate할 때 데이터를 바인딩 해줘야하는 두줄의 소스를 한줄로 줄이는 것으로 볼 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
class ExampleActivity extends Activity {
@BindView(R.id.title) TextView title;
@BindView(R.id.subtitle) TextView subtitle;
@BindView(R.id.footer) TextView footer;
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
set ContentView(R.layout.simple_activity);
ButterKnife.bind(this);
// TODO Use fields...
}
}
아래와 같이 여러 view의 listener도 bind한번으로 가능하게 한다.1
2
3
4
5
6
7
8
@OnClick({ R.id.door1, R.id.door2, R.id.door3 })
public void pickDoor(DoorView door) {
if (door.hasPrizeBehind()) {
Toast.makeText(this, "You win!" , LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Try again" , LENGTH_SHORT).show();
}
}
- -
Data Binding 사용하였을 경우 Data Binding은 AndroidSDK에서 지원하기 때문에 공식 API문서를 참고한다 Data Binding
1. gradle setting
app의 build.gradle에 다음 소스를 추가한다.
1
2
3
4
5
6
7
// app\build.gradle 중 일부
android {
....
dataBinding {
enabled = true
}
}
2. example 아래 xml파일에서 기존 xml과 다른 부분을 찾자면 tag 와 tag 와 android:text=”@{user.firstName}” 이 될 것이다. Data Binding을 사용하기 위해서는 LinearLayout과 같은 사용자의 View를 으로 감싸고 그 뒤에 data요소와 view요소를 추가한다. 레이아웃 내에서 @{} 를 통해서 속성을 불러올 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?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 >
1
2
3
4
5
6
7
8
public class User {
public final String firstName;
public final String lastName;
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
이제 activity에서 바인딩을 해주면 된다.1
2
3
4
5
6
7
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
User user = new User("Test" , "User" );
binding.setUser(user);
}
더 자세한 내용은 위에 링크한 안드로이드 공식 문서를 찾아보면 된다.
Data Binding, ButterKnife 후기