일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 캐치마인드
- 자취필수템
- 어떻게 나답게 살 것인가
- 북한살둘레길
- 아비투스
- 면접
- 한달어스
- 1일1커밋
- 목적 중심 리더십
- 베드테이블
- 끝말잇기
- 소프시스 밤부 좌식 엑슬 테이블
- 한달브런치북만들기
- 함수형 프로그래밍
- 커스텀린트
- 브런치작가되기
- 프래그먼트
- 테트리스
- 안드로이드
- 재택근무
- 베드트레이
- 한단어의힘
- 지지않는다는말
- 한달독서
- 리얼하다
- 목적중심리더십
- 좌식테이블
- 슬기로운 온라인 게임
- 소프시스
- T자형인재
- Today
- Total
정상에서 IT를 외치다
[Android, Databinding] 데이터 바인딩 이벤트 처리 본문
안녕하세요. 블랙진입니다.
데이터바인딩에 관한 3번째 포스팅으로 이벤트 처리 방법에 대해 알아보겠습니다. 데이터 바인딩에 관한 기본적인 내용 및 사용법은 데이터바인딩 사용기에서 확인하시면 됩니다.
1. 데이터바인딩 사용기
이벤트 처리
데이터 바인딩을 사용하여 뷰에 발송되는 이벤트를 처리하는 식으로 onClick 을 예로 들 수 있습니다. 이벤트 처리 방법은 두 가지가 있습니다.
1. 메서드 참조
이벤트를 핸들러 메서드에 직접 바인딩 하는 방법입니다.
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.activity = this@MainActivity
}
fun btnClick(view: View) {
Toast.makeText(this, "btnClick",Toast.LENGTH_SHORT).show()
}
}
메서드 참조 식일 경우 btnClick()에 View 파라미터를 꼭 지정해 주어야 합니다. 이벤트 처리 방법의 또 하나인 리스너 바인딩에서는 반대로 View 파라미터를 빼 주어야 정상적으로 동작합니다.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="activity"
type="com.tistory.black_jin0427.mydatabindingexample.MainActivity"/>
</data>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:text="activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{activity::btnClick}"/>
</LinearLayout>
</layout>
acitivity 라는 variable 을 <layout> 안에 선언해줍니다.
button 의 onClick 에 actvitiy:btnClick 라고 입력해 주면 원하는 동작이 이뤄 집니다.
2. 리스너 바인딩
이벤트 발생 시 실행되는 바인딩 식입니다. 메서드 참조와 비슷하지만, 리스너 바인딩을 사용하면 임의의 데이터 바인딩 식을 실행할 수 있습니다. 이 기능은 Android Gradle Plugin for Gradle 버전 2,0 이상에서 사용할 수 있습니다.
-2.1 데이터가 없는 경우
MainActivity.kt
fun btnClick() {
Toast.makeText(this, "btnClick",Toast.LENGTH_SHORT).show()
}
메서드 참조와 달리 View 파라미터를 제거해 주어야 합니다.
activity_main.xml
<Button
android:text="activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{() -> activity.btnClick()}"/>
-2.1 데이터가 있는 경우
SimaplModel.kt
class SampleModel(mTitle: String) {
val title = ObservableField<String>()
init {
title.set(mTitle)
}
}
데이터를 넣어주기 위해서는 model 을 생성해 주어야 합니다. title 변수 1개를 가지는 모델을 위와 같이 만들어 줍니다.
MainAcitivty.kt
val simpleModel = SampleModel("Android DataBinding")
binding.model = simpleModel
SimpleModel 의 mTitle 파라미터에 "Android DataBinding" 변수를 넣어 선언 후 바인딩 연결
fun btnClick(title: String) {
Toast.makeText(this, "title : $title",Toast.LENGTH_SHORT).show()
}
btnClick 에 title 변수를 추가해 줍니다.
activity_main.xml
<variable
name="model"
type="com.tistory.black_jin0427.mydatabindingexample.SampleModel"/>
<data></data> 사이에 SampleModel 을 추가해 줍니다.
<Button
android:text="activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{() -> activity.btnClick(model.title)}"/>
activity.btnClick 변수에 model.title 을 설정해 주면 SampleModel 을 선언할 때 설정해 둔 "Android DataBinding" 을 출력하게 됩니다.
3. 심화과정
이벤트 처리와 바인딩 어댑터를 이용한 재밌는 예제를 작업해 보겠습니다.
Title 과 SubTitle 을 화면에 보여주고 버튼을 눌렀을 때 애니메이션 효과와 함께 visible 되거나 inVisible 이 되는 예제를 만들어 보겠습니다.
3-1. activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="model"
type="com.tistory.black_jin0427.mydatabindingexample.SampleModel"/>
</data>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
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:visibility="@{model.visible}"
android:text="@{model.title}"
app:visibleAnimType="@{1}"
app:goneAnimType="@{2}"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="@{model.visible}"
android:text="@{model.subtitle}"
app:visibleAnimType="@{1}"
app:goneAnimType="@{2}"/>
<Button
android:text="model"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{() -> model.onButtonClick()}"
/>
</LinearLayout>
</layout>
model 1개를 데이터를 가지고 있는 xml 입니다.
3-2. MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
val simpleModel = SampleModel("Android DataBinding","Simple Example", true)
binding.model = simpleModel
}
}
SampleModel 을 생성할 때 3가지 파라미터를 넣어줍니다. 각각 title, subtitle, visible 을 나타냅니다.
3-3. SampleModel.kt
class SampleModel(
mTitle: String,
mSubtitle: String,
mVisible: Boolean
) {
val title = ObservableField<String>()
val subtitle = ObservableField<String>()
val visible = ObservableField<Boolean>()
init {
title.set(mTitle)
subtitle.set(mSubtitle)
visible.set(mVisible)
}
fun onButtonClick() {
val temp = visible.get() ?: true
visible.set(!temp)
}
}
모델은 3가지 변수과 1개의 이벤트 리스너를 가지고 있습니다.
onButtonClick 의 역활은 visible 값은 true 는 false 로 false 는 true 값으로 변경해 줍니다.
3-4. BindingAdapter.kt
@BindingAdapter(value = ["android:visibility", "visibleAnimType", "goneAnimType"], requireAll = true)
fun animationBindingMethod(view: View,
visible: Boolean,
visibleAnimType: Int,
goneAnimType: Int) {
if(visible) {
when(visibleAnimType) {
1 -> {
val anim = AlphaAnimation(0.0f, 1.0f).apply {
fillAfter = true
duration = 700
}
view.startAnimation(anim)
}
}
} else {
when(goneAnimType) {
2 -> {
val anim = AlphaAnimation(1.0f, 0.0f).apply {
fillAfter = true
duration = 700
}
view.startAnimation(anim)
}
}
}
}
BindingAdapter,kt 는 코틀린에서 사용하는 패키지 단위 함수입니다. 자바로 치면 싱글톤 객체나 함수를 만들 때 사용하는 방법입니다.
BindingAdapter() 에는 3가지 변수가 있고 requireAll = true 로 설정했습니다. 이를 통해 3가지 변수를 모두 xml 에 적어 주어야 컴파일 에러없이 작동됩니다.
SampleModel 의 버튼 이벤트를 기억하시나요?
fun onButtonClick() {
val temp = visible.get() ?: true
visible.set(!temp)
}
버튼을 누르면 visible 변수의 Boolean 값이 변합니다. 이는 ObservableField 를 통해 xml 에 바인딩 되어있는 뷰에 변화를 줍니다.
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="@{model.visible}"
android:text="@{model.title}"
app:visibleAnimType="@{1}"
app:goneAnimType="@{2}"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="@{model.visible}"
android:text="@{model.subtitle}"
app:visibleAnimType="@{1}"
app:goneAnimType="@{2}"/>
xml 에서 2가지 TextView 에 android:visibility 에서 @{model.visible} 을 설정한게 보이시죠? 이 visible 값이 변하게 되면 BindingAdapter 에서 정의한 animationBindingMethod 가 실행됩니다. 이때 visibleAnimType 값과 goneAnimType 값은 각각 1과 2의 값이 설정되게 했습니다.
저는 visibleAnimType 과 goneAnimType 에 int 값을 주어 원하는 애니메이션 효과를 int 변수에 따라 동작할 수 있게 구성해보았습니다. 이런식으로 코드를 짜면 원하는 view 에 원하는 애니메이션 효과를 간편하게 정의할 수 있을 것 같습니다. 혹시 더 좋은 방법을 알고 있으시다면 댓글 및 공유 부탁드리겠습니다:)
<참고자료>
'안드로이드' 카테고리의 다른 글
[리액티브 프로그래밍] 리액티브 연산자 입문 (0) | 2018.12.19 |
---|---|
[리액티브 프로그래밍] 리액티브 프로그래밍 이란? (0) | 2018.12.18 |
[번역] MVVM 디자인 패턴의 기본 이해 (0) | 2018.12.13 |
[Android, Koin] 코인을 사용한 의존성 주입 기본 예제 (4) | 2018.12.05 |
[Android Architecture Component] 라이프 사이클 (0) | 2018.11.27 |