binding 글 링크
개념-데이터-바인딩data-Binding (1)
개념-데이터-바인딩data-Binding (2)
개념-데이터-바인딩data-Binding (3)
개념-데이터-바인딩data-Binding (4)
개념-데이터-바인딩data-Binding (5)
View의 이벤트 처리방법에는 익명 클래스 or 인터페이스 구현(Implements) 등 여러 방법이 존재합니다.
//1. 람다식
button.setOnClickListener(view -> Log.d(TAG, "Click"));
//2. 익명 클래스
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "Click");
}
});
//3. 인터페이스 구현 (implements)
public class MainActivity implements View.OnClickListenr {
button.setOnClickListener(this);
@Override
public void onClick(view v) {
Log.d(TAG, "Click");
}
}
1. 이벤트 처리
DataBinding을 메서드 또는 리스너를 바인딩 하여 이벤트 처리를 할 수 있습니다. 컴파일 시 처리가 되므로, 바인딩 하려는 메서드가 존재하지 않거나 잘못 되었을 경우 런타임 에러가 발생하는 것이 아니라 컴파일 에러가 발생합니다. 데이터 바인딩을 이용한 방법에는 메서드 참조, 리스너 바인딩 두 가지 방법이 있습니다.
2. 메서드 참조하는 방식
class MyHandlers {
fun onClickFriend(view: View) { ... }
}
결합 표현식은 다음과 같이 뷰의 클릭 리스너를 onClickFriend() 메서드에 할당할 수 있습니다.
<?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>
TextView에 android:onClick="@{handlers::onClickFriend}"로 정의 함으로써,메서드를 직접 바인딩 하였습니다. "variable::메서드명" 이 아닌 "variable.메서드명" 으로 작성해도 동작 하지만 deprecated 되어 "::" 사용을 권고하고 있습니다.
또한, 바인딩 하려는 메서드는 해당 리스너의 메서드 형태와 동일 해야 합니다. 예를들어 onClick 메서드의 경우, 아래와 같은 형태이므로 return type 이 void 이고 매개변수로 View 가 있으므로 이 형태로 바인딩 메서드를 작성 해야합니다.
마지막으로 레이아웃 파일에 추가한 MyHandlers 객체를 설정 합니다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.handlers = MyHandlers()
}
3. 메서드 참조 구현 코드
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="handlers" type="com.project.databindingevent.MyHandlers"/>
<variable name="user" type="com.project.databindingevent.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:textSize="50sp"
android:text="@{user.firstName}"
android:onClick="@{handlers::onClickFriend}"
/>
</LinearLayout>
</layout>
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.user = User("Test", "User")
binding.handlers = MyHandlers(this)
}
}
data class User(val firstName: String, val lastName: String)
class MyHandlers(val context : Context) {
fun onClickFriend(view: View) {
Toast.makeText(context, "Click", Toast.LENGTH_SHORT).show()
Log.d(TAG, "Click")
}
}
4. 리스너 바인딩 하는 방식
class Presenter {
fun 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>
리스너는 람다 형태로 표현 합니다. 바인딩이 필요한 이벤트 리스너를 자동으로 생성하고, 이벤트가 발생하면 바인딩 된 식을 실행하는 형태입니다.
위의 예시에서는 onClick(view : View) 로 전달되는 view 매개변수를 지정하지 않았습니다. 리스너를 바인딩 할때는 모든 매개변수를 지정하거나, 지정하지 않고 사용 할 수 있습니다. 매개변수를 지정하면 메서드에 해당 변수를 그대로 사용 할 수 있습니다. 예시는 아래와 같습니다.
class Presenter {
fun onSaveClick(view: View, task: Task){}
}
android:onClick="@{(theView) -> presenter.onSaveClick(theView, task)}"
이때 리스너 안에 바인딩 된 식은 발생한 이벤트 리스너의 return type 과 동일한 type 을 return 해야 합니다.
위에 data태그 안의 variable를 선언해줍니다.
data class Task(val firstName: String, val lastName: String)의 값으로 임의의 데이터 결합 표현식을 실행할 수 있습니다.
android:onClick="@{() -> presenter.onSaveClick(task)}" 리스너 바인딩은 메서드 참조와 달리 리턴타입만 일치시키면 됩니다
return type void만 일치시켜 줍니다.
5. 리스너 바인딩 구현 코드
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="task"
type="com.project.databindingeventlistener.Task" />
<variable
name="presenter"
type="com.project.databindingeventlistener.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)}"
android:text="버튼"
android:textSize="100sp" />
</LinearLayout>
</layout>
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.task = Task("Test", "User")
binding.presenter = Presenter(this)
}
}
class Presenter(val context : Context) {
fun onSaveClick(task: Task){
Toast.makeText(context, "${task.firstName}, ${task.lastName}" , Toast.LENGTH_SHORT).show()
}
}
data class Task(val firstName: String, val lastName: String)
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