ViewBinding(뷰바인딩) 사용하기

pnlkc·2022년 5월 31일
0
post-thumbnail
post-custom-banner

ViewBinding 이란?


뷰바인딩은 안드로이드의 뷰를 xml 파일이 아닌 액티비니나 프래그먼트 상에서 바로 작업하기 위해 사용하는 기능이다.

기존에는 kotlin-android-extensions을 사용하거나 findViewById를 사용했지만
kotlin-android-extensions는 deprecated 되었고, findViewById는 뷰의 갯수가 많아지면 코드가 복잡해진다.

이러한 상황 속에서 뷰바인딩이 등장하게 되었고 간단한 설정만 하면 뷰에 쉽게 접근하여 작업이 가능해진다.

build.gradle 설정 (Module 수준)


뷰바인딩을 사용하려면 모듈 수준build.gradle에서 android 블럭 안에 아래 내용을 추가한다.

android {
	... (생략) ...
    
    // 아래 부분 추가
    buildFeatures {
        viewBinding true
    }
}

추가하면 우측 상단의 Sync Now를 클릭한다.

액티비티(Activty)에서 뷰바인딩 사용하기


뷰바인딩은 액티비티와 프래그먼트에서 초기화 방법이 다르다.

이유는 액티비티와 프래그먼트의 생명주기(Lifecycle)가 다르기 때문이다.

우선 액티비티에서는 아래와 같이 사용한다.

class MainActivity : AppCompatActivity() {

	// binding 변수를 lateinit var로 생성한다
    lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // inflate(layoutInflater)로 초기화 한다
        binding = ActivityMainBinding.inflate(layoutInflater)
        
        // binding.root 뷰를 화면에 표시하도록 설정
        setContentView(binding.root)
}

여기서 binding 변수의 자료형은 아래의 규칙을 가지고 만들어진다.

각각의 액티비티나 프래그먼트에 연결된 xml 파일을 이름을 파스칼 표기법으로 변경하고 이름 끝에 Binding을 추가하여 만들어진다.

예를 들어, 메인 액티비티의 경우 activity_main.xml와 연결되는데 이를 파스칼 표기법으로 바꾸면 ActivityMain이 되고 끝에 Binding이 추가되어 ActivityMainBinding이 되는 것이다.

같은 방법으로 my_custom_activity.xml와 연결된 액티비티의 경우 MyCustomActivityBinding을 inflate한 값으로 binding 변수를 초기화해주면 된다.

프래그먼트(Fragment)에서 뷰바인딩 사용하기


일반적으로 프래그먼트는 뷰보다 생명주기가 더 길다. 즉, 뷰가 Destroy 되어도 프래그먼트는 Destroy 되지 않을 수 있다. 이 때 프래그먼트에 선언된 binding 변수는 파괴된 뷰를 계속 참조하기 있기 때문에 메모리 누수가 발생하게 된다. 때문에 뷰가 Destroy 되었을 때 binding 값을 초기화하는 방법으로 메모리 누수를 방지해야 한다.

때문에 프래그먼트에서는 뷰바인딩을 아래와 같이 사용한다.

class MainFragment : Fragment() {

	// 메모리 관리를 위해 _binding을 nullable 타입으로 선언하고 null로 초기화한다
    private var _binding: FragmentMainBinding? = null
    // binding은 _binding을 not null 처리하고 getter를 통해 값을 받아온다
    private val binding get() = _binding!!
    
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?,
    ): View {
    
    	// binding이 아닌 _binding을 inflate를 통해 초기화해준다
    	_binding = FragmentMainBinding.inflate(inflater, container, false)
        
        ... (생략) ...
        
        // binding.root 뷰를 return 한다
        return binding.root
     }
   
	override fun onDestroyView() {
        super.onDestroyView()
        // 뷰가 Destroy될 때 _binding을 null로 초기화한다
        _binding = null
    }
}

추가로, bindingbinding = _binding!!으로 바로 값을 가져오지 않고 binding get() = _binding!!으로 가져오는지 궁금하신분은 이 블로그 글에 정리가 매우 잘되어 있으니 읽어보시면 좋을거 같습니다.

뷰바인딩을 통해 뷰 작업하기


뷰바인딩 설정이 끝나면 뷰를 뷰바인딩을 통해 작업할 수 있게된다.

이때 액티비티나 프래그먼트와 결합하는 뷰(xml파일)의 이름이 자동 생성되었던 것처럼 결합된 뷰 안에 있는 TextView나 ImageView 같은 뷰의 참조값도 자동 생성된다.

예를 들어 @+id/text_view라는 아이디를 가진 TextView는 binding.textView를 통해 사용할 수 있다.

마찬가지로 @+id/add_btn 아이디의 Button은 binding.addBtn을 통해 사용할 수 있다.

// 아래와 같이 버튼을 누르면 토스트 메세지가 나타나도록 하는 등으로 사용할 수 있다
binding.addBtn.setOnClickListener {
	Toast.makeText(this, "추가버튼 눌림!", Toast.LENGTH_SHORT).show()
}
profile
안드로이드 개발 공부 블로그
post-custom-banner

0개의 댓글