본문 바로가기

소소한 코딩 이야기/Android

View Binding 사용하기

● View Binding?

- View Binding 기능을 사용하면 뷰와 상호작용하는 코드를 쉽게 작성

- 모듈에서 사용 설정된 View Binding은 모듈에 있는 각 XML 레이아웃 파일의 결합 클래스를 생성

- 바인딩 클래스의 인스턴스에는 상응하는 레이아웃에 ID가 있는 모든 뷰의 직접 참조가 포함

 

● 적용방법

1. View Binding 요소를 build.gradle 파일에 추가

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.2"

	...

    //뷰바인딩 사용 설정
    buildFeatures {
        viewBinding = true
    }
}

 

2. Activity에서 View Binding 사용 (onCreate( ) 메서드에서 구현)

  1) 생성된 Binding 클래스에 포함된 정적 inflate( ) 메서드를 호출 -> Activity에서 사용할 Binding 클래스 인스턴스 생성

  2) getRoot( ) 메서드를 호출하거나 Kotlin 속성 구문을 사용하여 루트 뷰 참조를 가져옴

  3) 루트 뷰를 setConcentView( ) 에 전달하여 화면상의 활성 뷰로 만듦

  4) Binding 클래스 인스턴스를 사용하여 뷰의 참조가 가능

class MainActivity : AppCompatActivity() {

    private var activityMainBinding : ActivityMainBinding? = null

    //메모리에 화면이 올라갔을 때
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        //메인 액티비티 -> 액티비티 메인 바인딩
        //자동으로 완성된 액티비티 메인 바인딩 클래스 인스턴스를 가져왔다.
        val binding = ActivityMainBinding.inflate(layoutInflater)
        activityMainBinding = binding

        //바인딩과 연결
        setContentView(activityMainBinding!!.root)
        
        activityMainBinding?.bottomNav?.setOnNavigationItemSelectedListener(onBottomNevItemSelectedListener)
        
     }
}

 

3. 프래그먼트에서 View Binding 사용(onCreateView( ) 메서드에서 구현)

  1) 생성된 Binding 클래스에 포함된 정적 inflate( ) 메서드 호출 -> 프래그먼트에서 사용할 Binding 클래스 인스턴스 생성

  2) getRoot( ) 메서드를 호출하거나 Kotlin 속성 구문을 사용하여 루트 뷰 참조를 가져옴

  3) onCreateView( ) 메서드에서 루트 뷰를 반환하여  화면상의 활성 뷰로 만듦

inflate( ) 메서드를 사용하면 LayoutInflater를 전달해야 합니다. 레이아웃이 이미 확장되어 있다면 결합 클래스의 정적 bind( ) 메서드를 호출하면 됩니다.

  4) Binding 클래스 인스턴스를 사용하여 뷰의 참조가 가능

class HomeFragment : Fragment() {

    private var fragmentHomeBinding : FragmentHomeBinding? = null

    var count: Int = 0
    
    ...

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        //뷰바인딩 가져오기
        //홈프레그먼트 -> 프레그먼트 홈 바인딩
        val binding = FragmentHomeBinding.inflate(inflater, container, false)
        fragmentHomeBinding = binding

        fragmentHomeBinding?.homeFragmentBtn?.setOnClickListener {
            count = count + 1
            fragmentHomeBinding?.homeFragmentTextView?.text = "홈 $count"
        }

        return fragmentHomeBinding!!.root
    }

 

★ 프래그먼트는 뷰 보다 오래 지속됩니다.  그렇기 때문에 프래그먼트의 onDestroyView( ) 메서드에서 Binding 클래스 인스턴스 참조를 super가 실행되기 전에 null 값으로 변경하여 정리해 줍니다. (메모리 관리에 좋음!)
    override fun onDestroyView() {

        fragmentHomeBinding = null

        super.onDestroyView()
    }

 

● findViewById 와의 차이점

1. Null Point Exception 으로 부터 안전

  - View Binding은 뷰의 직접 참조를 생성하므로 유효하지 않은 뷰 ID로 인해 null point exception이 

    발생할 위험이 없음

  - 레이아웃의 일부 구성에만 뷰가 있는 경우 binding 클래스에서 참조를 포함하는 필드가 @Nullable로

    표시

2. 클래스 변환 예외가 발생할 위험이 없음

  - 각 바인딩 클래스에 있는 필드의 유형이 XML 파일에서 참조하는 뷰와 일치하기 때문에 클래스 변환

    예외가 발생할 위험이 없음

 

→ 이러한 차이점은 레이아웃 코드 사이의 비호환성으로 인해 런타임이 아닌 컴파일 시간에 빌드가 실패하게

    된다는 것을 의미

 

 

 

※참고자료

-안드로이드 공식문서

developer.android.com/topic/libraries/view-binding

 

뷰 결합  |  Android 개발자  |  Android Developers

뷰 결합 기능을 사용하면 뷰와 상호작용하는 코드를 쉽게 작성할 수 있습니다. 모듈에서 사용 설정된 뷰 결합은 모듈에 있는 각 XML 레이아웃 파일의 결합 클래스를 생성합니다. 바인딩 클래스의

developer.android.com

-개발하는 정대리님의 Youtube영상