dataBinding
앱의 데이터 소스와 레이아웃의 구성요소를 결합할 수 있게 해주는 Android JetPack 라이브러리
findViewById를 쓰지 않고, 데이터 소스와 레이아웃을 결합해주는 방식
https://developer.android.com/topic/libraries/data-binding/start?hl=ko
🚨 장점
1. findViewById()를 사용하지 않아도 된다. 자동으로 xml에서 만든 View들을 만들어준다.
2. data 가 바뀌면 자동으로 View 를 변경해준다.
3. 코드의 가독성 이 좋아진다.
🚨 사용 방법 , 예제 코드
build.gradle(:app)
dataBinding 의 enabled 를 true 로 설정합니다.
android {
...
dataBinding {
enabled = true
}
}
xml 레이아웃 - activity_main.xml
데이터 바인딩을 사용하기 위해 레이아웃 파일 전체를 <layout> 태그로 감쌉니다.
그 안에 <data> 태그 안의 <variable> 태그로 변수를 선언합니다.
variable 태그는 데이터 소스와 연결해주기 위한 태그입니다.
저는 액티비티 와 UserModel 데이터 클래스를 사용하기 위해 variable 태그에 선언하였습니다.
액티비티 데이터 소스의 변수를 사용하려면
"@{activity.nm_date}" 와 같은 방식으로 사용합니다.
액티비티 데이터 소스의 메소드를 사용하려면
android:onClick="@{() -> activity.onClickGoWeather()}" 와 같은 방식으로 사용합니다.
android:visibility="@{activity.isClickedBtnText == true ? View.GONE : View.VISIBLE}" 처럼
액티비티 데이터 소스의 변수값에 따라 값을 다르게 표시할 수 도 있습니다.
저는 View 도 사용하기 위해 <data> 안에 View 를 import 하는 소스도 추가하였습니다.
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View" />
<variable
name="activity"
type="com.eun.myweatherkotlin_mvvm_01.view.MainActivity" />
<variable
name="user"
type="com.eun.myweatherkotlin_mvvm_01.data.model.UserModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context=".view.MainActivity" >
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@color/amber_200"
android:elevation="10dp"
android:gravity="center"
android:text="메인화면"
android:textColor="@color/black"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/ll_date"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/ll_date"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginTop="50dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="20dp"
android:weightSum="100"
android:orientation="horizontal"
android:background="@drawable/bg_custom_title_name"
android:gravity="center"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title" >
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="30"
android:layout_marginRight="2dp"
android:gravity="right|center_vertical"
android:text="@{activity.nm_date}"
android:textStyle="bold"
android:textColor="@color/white"
android:textSize="20dp" />
<TextView
android:id="@+id/tv_date"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="70"
android:layout_marginRight="2dp"
android:gravity="left|center_vertical"
android:text="@{user.date}"
android:textColor="@color/white"
android:textSize="20dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_name"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginTop="50dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="20dp"
android:weightSum="100"
android:orientation="horizontal"
android:background="@drawable/bg_custom_title_name"
android:gravity="center"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ll_date" >
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="30"
android:layout_marginRight="2dp"
android:gravity="right|center_vertical"
android:text="@{activity.nm_name}"
android:textStyle="bold"
android:textColor="@color/white"
android:textSize="20dp" />
<TextView
android:id="@+id/tv_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="70"
android:layout_marginRight="2dp"
android:gravity="left|center_vertical"
android:text="@{user.name}"
android:textColor="@color/white"
android:textSize="20dp" />
</LinearLayout>
<Button
android:id="@+id/btn_goWeather"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:paddingLeft="30dp"
android:paddingRight="30dp"
android:text="Go Weather"
android:onClick="@{() -> activity.onClickGoWeather()}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ll_name" />
<Button
android:id="@+id/btn_showToast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:paddingLeft="30dp"
android:paddingRight="30dp"
android:text="Show Toast"
android:onClick="@{() -> activity.onClickShowToast(user.date+'/'+user.name)}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_goWeather" />
<Button
android:id="@+id/btn_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:paddingLeft="30dp"
android:paddingRight="30dp"
android:text="@{activity.isClickedBtnText == true ? activity.btnTextShow : activity.btnTextHide}"
android:onClick="@{() -> activity.onClickBtnText()}"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/tv_text"
app:layout_constraintTop_toBottomOf="@+id/btn_showToast" />
<TextView
android:id="@+id/tv_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:paddingLeft="10dp"
android:layout_gravity="center_vertical"
android:text="@{activity.nm_text}"
android:visibility="@{activity.isClickedBtnText == true ? View.GONE : View.VISIBLE}"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/btn_text"
app:layout_constraintTop_toBottomOf="@+id/btn_showToast" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
UserModel.kt
data 객체를 view 와 바인딩하기 위해 UserModel 이라는 이름의 data class 를 만듭니다.
package com.eun.myweatherkotlin_mvvm_01.data.model
data class UserModel(
var date: String,
var name: String
)
MainActivity.kt
레이아웃과 결합할 수 있게 DataBindingUtil.setContentView() 을 사용해서
데이터 소스와 레이아웃의 구성요소를 결합시켜 줍니다.
binding.activity 는 레이아웃의 activity 를 this@MainActivity 로 선언하고
binding.user 는 레이아웃의 user 를 UserModel 클래스의 객체로 결합하여 set 해주는 것을 의미합니다.
액티비티 Activity vs 프래그먼트 Fragment 의 사용방식 입니다.
//Activity
val binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
//Fragment
val binding = DataBindingUtil.inflate(inflater, R.layout.activity_main, container, false)
package com.eun.myweatherkotlin_mvvm_01.view
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import com.eun.myweatherkotlin_mvvm_01.R
import com.eun.myweatherkotlin_mvvm_01.data.model.UserModel
import com.eun.myweatherkotlin_mvvm_01.databinding.ActivityMainBinding
import com.eun.myweatherkotlin_mvvm_01.util.stringTime
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding //activity_main.xml 을 바인딩
var nm_date = "날짜 : "
var nm_name = "이름 : "
var nm_text = MainActivity::class.java.simpleName
var isClickedBtnText = false
var btnTextHide = "HIDE"
var btnTextShow = "SHOW"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main) //DataBindingUtil 을 통해 view layout 초기화
binding.activity = this@MainActivity //binding 객체의 activity 를 MainActivity 로 설정
binding.user = UserModel(stringTime, "홍길동") //UserModel 객체를 초기화하여 binding 객체의 user 에 set 해준다
}
/* WeatherActivity 로 이동 */
fun onClickGoWeather() {
val intent = Intent(this, WeatherActivity::class.java)
startActivity(intent)
}
/* Toast 띄우기 */
fun onClickShowToast(text: String) {
Toast.makeText(this, text, Toast.LENGTH_SHORT).show()
}
/* isClickedBtnText 에 따라 TEXT 표시 여부 변경하기 */
fun onClickBtnText() {
isClickedBtnText = !isClickedBtnText
binding.invalidateAll() //UI 새로고침 하기 위해서 새로운 리바인드를 요청
}
}
CommonUtil.kt
CommonUtil 은 현재시간을 사용하기 위해 만든 공통 파일입니다.
package com.eun.myweatherkotlin_mvvm_01.util
import java.text.SimpleDateFormat
import java.util.*
// 현재시간을 가져오기
val now: Long = System.currentTimeMillis()
// 현재 시간을 Date 타입으로 변환
val date = Date(now)
// 날짜, 시간을 가져오고 싶은 형태 선언
val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale("ko", "KR"))
// 현재 시간을 dateFormat 에 선언한 형태의 String 으로 변환
val stringTime = dateFormat.format(date)
// String 형태의 시간을 Long 형으로 변환
val longTime = dateFormat.parse(stringTime).time
//String 형태의 시간을 Date 형으로 변환
val dateTime = dateFormat.parse(stringTime)
결과 화면
감사합니당!
'📱 안드로이드 Android ~ Kotlin' 카테고리의 다른 글
[안드로이드/Android] 클린아키텍처 Clean Architecture (0) | 2021.09.09 |
---|---|
[Android/Firebase] Firebase 프로젝트 생성 및 앱 추가 (0) | 2021.09.05 |
[Android/Kotiln] MVVM 적용한 날씨 앱 만들기 (viewBinding, retrofit 사용) (0) | 2021.08.30 |
[Android/Kotiln] MVVM 적용한 ToDo 앱 만들기 (LiveData) (0) | 2021.08.13 |
안드로이드 아키텍쳐 컴포넌트 AAC (Android Architecture Components) (0) | 2021.08.06 |