본문 바로가기
Mobile : Android/Jetpack

[Jetpack AAC] View Binding 정리

by 신숭이 2021. 11. 15.

 

[Jetpack AAC] View Binding 정리

 

 

 

 

핵심 : findViewById 를 쓰지 않는다. 

 

 

뷰 바인딩은 각 XML 레이아웃 파일에 해당하는 바인딩 클래스(Binding Class)를 자동 생성하여 뷰에 대한 직접 참조를 가능케 한다. 기존에는 코틀린 합성 프로퍼티를 이용해서 했지만 코틀린 합성 프로퍼티는 이제 deprecated  예정이기에 공식적으로 이 방법을 쓰는게 맞다.

 

기본적인 뷰바인딩 사용방법과 3가지 사례(Activity에서 사용법, Fragment에서 사용법, ViewHolder에서 사용법)를 정리해보겠다.

 

 

 

준비

 

  • 안드로이드 스튜디오 3.6 이상 (Canary 11 이상) 에서 사용 가능
  • 모듈 수준 gradle 파일에 다음을 추가한다.
android{
	... 중략
    viewBinding {
         enabled = true
    }
}

이렇게 해도된다

android{
	...
    buildFeatures {
         viewBinding true
    }
}

 

 

이렇게하면 우리는 액티비티에서 다음 클래스를 참조할 수 있다.

예를 들어 MainActivity 라는 클래스가 있고 이 레이아웃 파일이 activity_main.xml 이라면 다음과 같은 클래스가 자동 생성되어 참조할 수 있다.

 

내가 구성한 XML 파일 : activity_main.xml 

자동 생성된 바인딩 클래스 : ActivityMainBinding.class

 

즉 자동 생성되는 이름 규칙은 _(언더바)를 기준삼아 카맬 표기법으로 생성된다. 이건 android 탐색창에서 나타나지 않는 클래스이다. (위와 같은 클래스를 만들라는게 아니다. 저건 자동 생성되는 것)

 

이런 규칙은 xml 레이아웃 파일 내에 뷰 id 에도 적용된다. 예를들어 android:id="@+id/button_back" 이라고 내가 아이디를 설정해 놓았다면, buttonBack 이라는 참조가 자동 생성된다. (뷰에 대해선 첫 글자가 소문자, 알 필요 없다. 자동생성이니깐!)

 

 

 

 

액티비티(Activity)에서 사용법

 

보통 다양한 변형이있는데, 결국 다 똑같은 코드이다. 제일 모범 답안을 고르라면 난 구글에서 제시하는 코드랩 예시를 고르겠다. XML 레이아웃에서 Back 버튼을 구현하기 위한 버튼 뷰가 있다고 가정하고, 아이디가 다음과 같을 떄 

 

android:id="@+id/button_back" 

 

아래와 같이 클릭 리스너를 붙이면 아주 Fancy 하다. 

 

class MainActivity : AppCompatActivity() {
	
    private val binding by lazy(LazyThreadSafetyMode.NONE){
        ActivityMainBinding.inflate(layoutInflater)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setConetentView(binding.root)
        
        binding.buttonBack.setOnClickListener { onBackPressed() }
    }
}

binding 상수는 XML 바인딩 클래스를 참조하는 변수로 이제부터 이 변수를 통해 뷰에 대한 접근을 시도할 수 있다.

 

 

 

 

프래그먼트(Fragment)에서 사용법

 

 

 

PlayerFragment 라는 클래스가 있고, 이 레이아웃을 fragment_player 가 표현하고 있다고 가정하자. 그럼 다음과 같이 바인딩 할 수 있다.

 

class PlayerFragment : Fragment() {

    private lateinit var binding: FragmentPlayerBinding
    
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View{
        binding = FragmentPlayerBinding.inflate(inflater)
        return binding.root
    }
}

 

이렇게 해도 된다.

 

class PlayerFragment : Fragment(R.layout.fragment_player) {

    private var binding: FragmentPlayerBinding? = null

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val fragmentPlayerBinding = FragmentPlayerBinding.bind(view)
        binding = fragmentPlayerBinding
    }

 

 

 

뷰홀더(ViewHolder)에서 사용법

 

 

안드로이드 개발을 하다보면 리사이클러뷰(RecyclerView) 등 각종 뷰 홀더를 쓸 일이 정말 많다. 여기서도 바인딩하는 법을 알아보면 다음과 같다. 리사이클러뷰에 들어갈 아이템은 item_raw.xml 파일에 레이아웃을 구성했다고 가정하면 다음과 같이 ItemRowBinding 이라는 바인딩 클래스를 이용하여 참조할 수 있다.

 

class ViewAdapter(var dataList:Array<DataModel>) 
	: RecyclerView.Adapter<ViewAdapter.MyViewHolder>(){

    inner class MyViewHolder(var binding : ItemRowBinding) : RecyclerView.ViewHolder(binding.root){
        fun bind(position:Int){
            binding.txtMusicName.text = dataList[position].name
            binding.txtMusicTime.text = dataList[position].time
            binding.btnMusicControl.setOnClickListener {
                .. 클릭 구현
            }
        }
    }

    // 바인딩
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        var binding = ItemRowBinding.inflate(LayoutInflater.from(parent.context),parent,false)
        return MyViewHolder(binding)
    }

    override fun getItemCount(): Int = dataList.size

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.bind(position)
    }
    
    ...

 

 

여기서 난 생성자에 Array를 넘겨줬지만 이는 다르게 구현해도 된다. 이것은 리사이클러뷰 구현 스타일 차이이므로 이번 포스트에서 다룰 내용이 아니다.

 

리사이클러뷰를 구현해본 적이 있다면 위 코드로 충분히 참고가 될 것 같다.

 

 

 

 

 

나는 바인딩 클래스를 자동 생성하기 싫다

 

 

특정 XML 파일에 대해서는 바인딩클래스를 생성하지 않고 싶은 경우가 있다. 그런 경우에는 XML 파일의 루트 뷰에 다음과 같은 속성을 추가해주면 된다.

 

<LinearLayout
        ...
        tools:viewBindingIgnore="true" >
        ...
</LinearLayout>

 

 

 

 

Reference

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

 

뷰 결합  |  Android 개발자  |  Android Developers

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

developer.android.com

 

 

 

끝.

 

댓글