본문 바로가기

개발 노트/Kotlin

코틀린의 ViewBinding과 DataBinding

# 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의 차이는 뭘까??

  1. ViewBinding의 속도가 더 빠르다
  2. DataBinding은 layout 태그를 사용하여 만든 레이아웃을 처리한다
  3. ViewBinding은 양방향바인딩을 지원하지 않는다
  4. ViewBinding이 DataBinding보다 퍼포먼스 효율이 좋고 용량이 절약되는 장점이 있다 (findViewById를 대체하기 위해 Binding을 쓴다면 ViewBinding 사용 권장)

 

 

 

 

# 뷰바인딩, 데이터바인딩 공식문서

https://developer.android.com/topic/libraries/view-binding?hl=ko

 

뷰 결합  |  Android 개발자  |  Android Developers

이 페이지는 Cloud Translation API를 통해 번역되었습니다. 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 뷰 결합은 뷰와 상호작용하는 코드를 더 쉽게 작성할

developer.android.com

https://developer.android.com/topic/libraries/data-binding?hl=ko

 

데이터 바인딩 라이브러리  |  Android 개발자  |  Android Developers

이 페이지는 Cloud Translation API를 통해 번역되었습니다. 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 데이터 결합 라이브러리 Android Jetpack의 구성요소 데이

developer.android.com