Android App Track⛺-039

MunkiJeon·2024년 8월 1일

TIL

목록 보기
56/59
post-thumbnail

TIL (Today I Learned)

* MVVM을 하려니 데이터 바인딩뷰 바인딩개념이 선행되어야 해서 먼저 적음

ViewBinding과 DataBinding의 관계ViewBinding과 DataBinding의 관계

데이터 바인딩

  • 데이터와 뷰를 연결하는 작업을 레이아웃에서 처리하는 기술
  • = 안드로이드의 xml 리소스에 data부착하는 것을 의미

데이터 바인딩을 사용하는 이유

XML 레이아웃 파일에서 화면 구성을 나타내고, 이 화면들을 코드에서 findViewById와 같은 메서드를 사용하여 연결해줍니다.
하지만 findViewById를 통한 검색은 번거로우며, 코드가 복잡해지고 유지보수가 어려워질 수 있습니다.

이러한 문제를 해결하기 위해 데이터 바인딩데이터와 뷰자동으로 연결해주는 바인딩 어댑터를 제공합니다.
이렇게 하면 XML 레이아웃 파일에서 직접 변수나 데이터를 바인딩할 수 있으며,
뷰를 조작할 때 직접 findViewById를 호출할 필요가 없어집니다.(오!😏)

장점은?

  1. 코드의 가독성과 유지보수가 쉽습니다 :
    바인딩 하게 되면 XML 레이아웃과 Kotlin 코드 사이의 강력한 연결을 만들어 코드를 더욱 읽기 쉽고 유지보수하기 쉽게 만듭니다.

  2. 널 안정성:
    Kotlin의 주요 특성인 널 안전성을 제공합니다.
    즉, 바인딩이 올바르게 구성되지 않은 경우 런타임에서 NPE(Null Pointer Exception)가 발생하지 않습니다.

  3. 생산성 향상:
    바인딩 어댑터를 사용하면 뷰를 찾는 로직을 작성할 필요가 없으므로 코드 작성 시간이 줄어들고 개발자의 생산성이 향상됩니다.

특징은?

  1. 당연히 findViewById()를 사용하지 않아도 된다.
    자동으로 xml에서 만든 View들을 만들어준다.
  2. RecyclerView 사용 시 각각의 item들을 set해주지 않아도 알아서 xml에서 처리할 수 있다.
  3. Observable(= 데이터의 변화를 계속 지켜보는 녀석,,,)을 이용해 실시간으로 데이터를 바꿔줄 수 있다.
    +LiveDataobserve 변수를 함께 사용하는 경우, 데이터의 변경이 일어날 때 자연스럽게 연결된 UI도 업데이트 시켜 UI와 데이터의 바인딩이 보장된다.
    (사실 이 기능이 없다면 데이터바인딩이라는 이름일 수 있을지 고민이 들긴 함.)

그럼 무조건 데이터 바인딩?

No! 데이터 바인딩(DataBinding) 기능을 사용하지 않는다면
빌드 시간 및 APK 크기 측면에서 가벼운 뷰 바인딩(ViewBinding) 사용 권장하기 때문입니다.

뷰 바인딩

  • findViewById를 대체할 수 있는 기능

뷰 바인딩을 사용하는 이유

  1. 일일이 View를 찾아 findViewById 하여 형변환할 필요 없음
  2. Type-Safety : 레이아웃 내에서 View만 찾아 정확한 View타입을 맵핑해 함
  3. Null-Safety : 레이아웃에 없는 ID접근시 에러 발생시켜 NullPointException을 방지
  4. 오류가 나면 런타임이 아닌 컴파일시 빌드 오류를 알려 준다
    (= 앱 실행전에 코드 변환과정에서 바로 애려 띄워준다는 얘기)
  5. 현재코틀린익스텐션같은경우는2021년에지원중단이될예정현재 코틀린 익스텐션 같은 경우는 2021년에 지원 중단이 될 예정

사용법

1. gradle 추가

plugins {// Kotlin Annotation Processing = "@"(Kotlin Annotation)사용시 추가
 ...
 id("kotlin-kapt")
}
// 안드로이드 스튜디오 3.6 ~ 4.0
android {
...
  dataBinding {//
      enable =  true
  }
  viewbinding {
  	  enable =  true
  }
}
android {// 안드로이드 스튜디오 4.0 이상
...
  buildFeatures {
      dataBinding = true
      viewBinding = true
  }
}

2. XML (데이터 바인딩!! 뷰 바인딩은 ID만 잘 넣어 두믄됨!!)

<?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>
      <variable
      name="user"
      type="com.example.selfstudy_kotlin.UserProfile" />
  </data>
  <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:orientation="vertical"
      tools:context=".MainActivity">
      <TextView
          android:id="@+id/firstName"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:text="@{user.firstName}" />
      <TextView
          android:id="@+id/lastName"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:text="@{user.lastName}" />
  </LinearLayout>
</layout>
  • 위와 같이 코드를 작성하면 내부의 name을 통해 데이터를 작성할 수 있게 됩니다.
  • android:text="@{user.firstName}"
    • 위와 같은 방식으로 코드를 사용할 수 있는데, 이를 이용하면 추가적인 작업 없이 viewdata를 표현해줄 수 있다.
    • 더 세부적인 상세 내용을 적는 등의 작업은(금액에 ,를 찍는다거나 하는 다른 가공 처리가 필요한 경우) bindingAdapter를 이용해서 작업을 진행할 수 있다.
    • 이를 통해 뷰에서 직접 데이터를 관리하는 느낌과 한 곳에 위치한 데이터와 UI를 통해 전체적인 가독성을 상승시킬 수 있다.
  • android:text="@={viewModel.encouragementMessage}"
    • 또한 위와 같이 EditText에서 @{ 가 아니라 @={로 시작하는 경우
      양방향 데이터바인딩이 이루어져 EditText가 가진 변수와 @={}안에 들어간 변수가 싱크를 유지하며 동일한 데이터로 매칭된다.
    • 이처럼 UI내에서 변수를 가지게 되는 경우에는 양방향 데이터 바인딩을 사용할 수 있다.

3-1. 액티비티

    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.user = UserProfile("지은", "이")//데이터 바인딩
		  binding.user = UserProfile("지은", "이")//뷰 바인딩
      }
  }

3-2. 프래그먼트

class BlankFragment : Fragment() {
    private var _binding: FragmentBlankBinding? = null
    // This property is only valid between onCreateView and
    // onDestroyView.
    private val binding get() = _binding!!
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentBlankBinding.inflate(inflater, container, false)
        val view = binding.root
        return view
    }
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.textView.text = "안녕"
    }
    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

그래서... 데이터 바인딩 ? vs 뷰 바인딩 ?

  • Data Binding과 View Binding은 동일하게 뷰를 직접 참조하는 바인딩 클래스를 생성한다.
  • View Bindingannotation 프로세싱의 일부만 사용하기 때문에,
    View BindingData Binding보다 컴파일 속도가 빠르다.
  • View Bindingtag 처리된 xml 사용이 불필요하다.
    단순하게 findviewbyid를 대체하기 위해서라면 View Binding을 사용하는 게 더 효율적이다.
  • Data BindingView Binding의 역할도 할 수 있고,
    추가적으로 동적 UI 콘텐츠 선언, 양방향 데이터 결합을 지원한다.

참고한 자료

데이터 바인딩 & 뷰 바인딩
https://velog.io/@lijunhyeong/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-Data-binding-%EC%9D%B4%EB%9E%80
https://todaycode.tistory.com/31 -***
https://velog.io/@ouowinnie/AndroidKotlin-03-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B0%94%EC%9D%B8%EB%94%A9Data-Binding-%EA%B8%B0%EC%B4%88

profile
공장자동화와 웹 개발을 핥아 먹다 앱 개발로 전향한 개발자의 키보드의 낡은 키캡⛑️

0개의 댓글