본문 바로가기
기타

[아롬 멘토링] 뷰 바인딩(View Binding)

by JongSeok 2023. 3. 30.

Android Studio는 클래스에서 해당 클래스에 대응되는 xml 파일의 뷰를 각각의 Id를 통해 접근합니다.

ViewBinding 이전

과거 android 초기에는 findViewById()라는 메소드를 통해 뷰에 접근했습니다.

findViewById의 뜻 그대로 Id를 통해 View를 찾는다는 의미인데

화면의 뷰가 1, 2개 라면 모르겠지만 화면이 복잡해지다 보면 위와 같이 코드가 불필요하게 길어지고 모든 뷰를 사전에 선언해줘야 한다는 단점이 있습니다.


findViewById의 단점을 보완하기 위해 나온 Kotlin Synthtic이 있습니다.

plugins {
    ...
    id 'kotlin-android-extensions'
}

app수준 build.gradle에 해당 플러그인을 추가하면 사용 가능합니다.

위에서 사용했던 findViewById를 사용할 필요 없이 뷰의 id에 바로 접근할 수 있습니다.

 

하지만 다음과 같은 문제로 Android Studio 버전 4.1에서 deprecated됩니다,,,

  • 뷰의 ID를 부여하는 과정에서 레이아웃에서 중복된 ID를 설정한 경우 NullPointException이 발생한다.
  • 실수의 여지가 매우 많다.
  • Kotlin만 지원 가능하다.

ViewBinding 이란?

findViewById와 Kotlin Synthtic의 단점을 보완하기 위해 ViewBinding이라는 개념이 등장합니다.

ViewBinding은 모듈에서 설정된 각 XML 레이아웃 파일의 Binding 클래스를 생성해 클래스를 통해 대응되는 레이아웃의 뷰 ID에 직접참조를 가능하게 합니다.

 

즉, ViewBinding을 사용하는 이유는 해당 클래스에 대응되는 xml의 각 요소에 정확히 접근할 수 있기 때문입니다.

 

사용방법

app수준 build.gradle에 viewBinding 옵션을 활성화합니다.

android {
    ...
    buildFeatures {
        viewBinding true
    }
}

Activity에서 viewBinding

class MainActivity : AppCompatActivity() {
    // 전역 변수로 바인딩 객체 지연 초기화 및 선언
    private val binding: ActivityMainBinding by lazy {
        ActivityMainBinding.inflate(layoutInflater)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // setContentView(R.layout.activity_main)
        setContentView(binding.root)

        binding.textView.text = "안녕하세요, 아롬입니다."
    }
}

Binding 클래스의 이름은 ex. MainActivity → ActivityMainBinding의 형태로 변경됩니다.

해당 xml 뷰의 ID 또한 ex. text_view → textView (언더바 제거, 카멜표기법)로 접근할 수 있습니다.

Fragment에서 viewBinding

class MainFragment: Fragment() {
    // Binding 객체에 ?를 붙여 null을 허용
    private var _binding: FragmentMainBinding? = null
    // Binding 변수 재선언
    private val binding get() = _binding!!

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        _binding = FragmentMainBinding.inflate(inflater, container, false)
        return binding.root
    }

    // 프래그먼트가 파괴될 때
    override fun onDestroy() {
        _binding = null
        super.onDestroy()
    }
}

 

728x90
반응형