# ViewBinding과 DataBinding 사용하는 이유
XML 레이아웃 파일을 만들고, 이 레이아웃을 코드에서 findViewById를 사용해서 연결해주는데
findViewById를 계속 쓰게되면 코드도 복잡해지고 유지보수도 어려워질 수 있는 문제가 발생한다
이러한 문제를 해결하기위해 ViewBinding과 DataBinding이 나왔는데 이를 사용하면
매번 findViewById를 사용하지 않고 바로 바인딩할 수 있어서 가독성이 좋고, 유지보수가 쉽다
ViewBinding과 DataBinding은 이런점에서 공통점을 가지지만 선언방식, 코드작성방식 등에서 차이가 있다
항상 ViewBinding과 DataBinding 쓸때마다 조금 헷갈려서 정리를 해보려고한다
# findViewById와의 차이점
1) Null 안정성 (Null Safety)
바인딩 기능을 사용하면, 앱이 레이아웃의 각 뷰를 직접 참조할 수 있게 해주는 안전한 코드를 자동으로 생성한다.
이는 뷰를 사용할때 'null' 값으로 인한 오류. 즉, 뷰가 아직 화면에 나타나지 않았는데 그 뷰를 사용하려고 할 때 생길 수 있는 문제들을 예방해준다
ex) 만약 레이아웃에 버튼이 있어야 하는데 아직 버튼이 생성되지 않았다면, 바인딩은 이를 안전하게 처리하여 앱이 충돌하지 않도록해준다.
또한, 만약 레이아웃의 일부만 뷰가 있다면, 뷰 바인딩은 해당 뷰가 '가능성 있는 null'(Nullable)임을 알려주어, 개발자가 더 주의 깊게 코드를 작성하도록 돕는다
2) 타입 안전성 (Type Safety)
XML 레이아웃 파일에서 정의된 뷰의 타입과 자동 생성된 바인딩 클래스의 필드 타입이 항상 일치하기 때문에, 타입이 서로 맞지 않아 발생할 수 있는 오류를 방지해준다
ex) 이미지 뷰(ImageView)에 텍스트를 설정하려고 하면 오류가 발생할 텐데, 바인딩을 사용하면 이런 실수를 할 가능성이 없어진다.
즉, 이미지 뷰는 이미지 뷰로, 텍스트 뷰는 텍스트 뷰로만 사용되게 하여, 잘못된 타입 사용으로 인한 오류가 발생하지 않도록 보장해준다
# ViewBinding 사용방법
먼저 build.gradle에 아래와같이 추가해준뒤 sync now를 눌러준다
// 뷰 바인딩
buildFeatures{
viewBinding = true
}
build.gradle(app)
Activity, Fragment에서 각각 사용하는 방법이 다르다. 이유는 엑티비티와 프레그먼트의 생명주기가 다르기 때문이라고 한다
- Activity에서 사용방법
class MainActivity : AppCompatActivity() {
// lateinit var로 엑티비티를 바인딩 시켜준다
private lateinit var binding : ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// inflate(layoutInflater)로 초기화
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root) // binding.root를 사용해서 뷰를 화면에 표시
binding.button.setOnClickListener {
...
}
}
}
-> lateinit var로 엑티비티를 바인딩 시켜준뒤
[뷰바인딩 기능을 사용할 때, 안드로이드 스튜디오는 레이아웃 파일의 이름을 기반으로 한 바인딩 클래스를 자동으로 생성한다. 이는 레이아웃에 있는 모든 뷰에 대한 참조를 포함하며, 이를 통해 코드에서 직접 뷰에 접근할 수 있게 해준다]
inflate(layoutInflater)를 사용해서 초기화시켜주고 binding.root를 사용해서 뷰가 화면에 보이도록 해준다
이렇게 바인딩을 시켜주면 binding.button 이런식으로 사용해서 바로 xml에 연결된 파일 이름을 불러올수있다!!
- Fragment에서 사용방법
class DonutListFragment : Fragment() {
// lateinit var로 프래그먼트를 바인딩
lateinit var binding : FragmentDonutListBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentDonutListBinding.inflate(inflater, container, false)
binding.textView.setOnClickListener {
...
}
return binding.root
}
}
-> 엑티비티와 바인딩을 초기화하는 부분이 다른것빼고는 비슷하다
이렇게 써주면 역시 쉽게 xml파일을 불러올 수 있다
# DataBinding 사용방법
이제 데이터바인딩 사용방법을 알아볼것이다
마찬가지로 build.gradle에 아래와같이 추가해준뒤 sync now를 눌러준다
// 데이터 바인딩
dataBinding {
enable = true
}
build.gradle(app)
- Activity에서 사용방법
일단 뷰바인딩과 가장 큰 차이는 데이터바인딩은 xml파일 전체를 <layout> </layout>으로 감싸줘야된다는것이다!!
layout으로 감싸주지 않으면 오류가 뜬다
<?xml version="1.0" encoding="utf-8"?>
<layout>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="btn 1"
android:textColor="@color/textpink"
android:textSize="15sp"
android:textStyle="bold"
android:layout_marginTop="10dp"
android:background="@drawable/button_radius_pink"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<FrameLayout
android:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button">
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
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.button.setOnClickListener {
...
}
}
}
-> lateinit var로 엑티비티를 바인딩 시켜준뒤
DataBindingUtil을 사용해서 바인딩 초기화를 시켜준다!
- Fragment에서 사용방법
역시 layout으로 감싸주는건 똑같고
class DonutListFragment : Fragment() {
lateinit var binding: FragmentDonutListBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_donut_list, container, false)
binding.textView.setOnClickListener {
...
}
return binding.root
}
}
-> 프레그먼트에서는 바인딩을 초기화하는 부분이 inflate이고
binding.root로 뷰를 리턴해주는 방식이다
# ViewBinding과 DataBinding의 차이
그러면 ViewBinding과 DataBinding의 차이는 뭘까??
- ViewBinding의 속도가 더 빠르다
- DataBinding은 layout 태그를 사용하여 만든 레이아웃을 처리한다
- ViewBinding은 양방향바인딩을 지원하지 않는다
- ViewBinding이 DataBinding보다 퍼포먼스 효율이 좋고 용량이 절약되는 장점이 있다 (findViewById를 대체하기 위해 Binding을 쓴다면 ViewBinding 사용 권장)
# 뷰바인딩, 데이터바인딩 공식문서
https://developer.android.com/topic/libraries/view-binding?hl=ko
https://developer.android.com/topic/libraries/data-binding?hl=ko
'개발 노트 > Kotlin' 카테고리의 다른 글
[Android] Activity Stack 및 backStack (0) | 2024.03.29 |
---|---|
버튼 눌렀을때 Fragment화면 나타내기 (0) | 2024.03.28 |
[Android] 엑티비티 생명주기(Activity Life Cycle) (0) | 2024.03.26 |
프로그래밍 기초 과제 - 계산기 (0) | 2024.03.25 |
버튼에 elevation 속성값을 지정했음에도 그림자가 안보일때 (0) | 2024.03.21 |