Stargazer

[Android] 뷰 바인딩 (View Binding) 본문

프로그래밍/Android

[Android] 뷰 바인딩 (View Binding)

COM2IT 2021. 7. 7. 00:42
반응형

뷰 바인딩이란?

말그대로 묶는건데, 레이아웃 xml 파일에 대한 액티비티 클래스를 정의 해줄 필요없이 자동으로 각 뷰에 대해 이어서(connect) 생성해주는 기능을 말한다.

 

뷰바인딩을 사용해야 하는 이유:

  1. 일일이 findViewById를 사용할 필요가 없다.
  2. Type-safe (레이아웃 내에서 정확한 view 타입을 찾아 맵핑함)
  3. Null-safe (레이아웃에 없는 id를 findViewById를 했을 때의 NullPointerException 방지)

뷰바인딩 하는 법:

첫번째로 build.gradle 파일을 수정해야한다.

프로젝트에서 build.gradle(Module) 파일을 열어서 다음과 같이 수정 해야한다.

android{
...
	viewBinding{
    	enabled = true
    }
...
}

문서를 보니까 4.0 버전 이상일때는 다르게 해야한다는데 필자는 4.0이상임에도 위의 코드가 먹히는 걸 보아 호환은 하는 것 같다.

 

이걸 수정한 후에 자동으로 안바뀌면 수동으로 상단에 Sync Now 를 눌러줘야 적용된다.

아니면 File -> Sync Projects with Gradle File 을 눌러줘야 한다고 한다.

 

 

뷰바인딩 작명 규칙

예를 들어 activity_main.xml 레이아웃 파일이 있다고 하면,

해당 레이아웃은 ActivityMainBinding 이라는 바인딩 클래스가 자동으로 생성된다.

(단어 언더바로 구분 ->단어 첫 대문자로 구분 + Binding)

 

 

예제

 

다음은 MainActivity 에서 SecondActivity로 인텐트를 통해 값을 전달하는 예시 이다.

 

우선 레이아웃 파일 activity_main.xml을 다음과 같이 바꾼다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <EditText
        android:id ="@+id/edt_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        ></EditText>


    <Button
        android:id="@+id/btn_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:backgroundTint="@color/white"
        android:text="다음 액티비티에 값 전달"
        android:textColor="@color/black"></Button>

</LinearLayout>

레이아웃 디자인 뷰

java 폴더 아래에 MainActivity.kt 파일을 다음과 같이 바꿔야한다.

package com.example.second_week

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.second_week.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding //자동 생성됨 (뷰바인딩 사용하면 이렇게됨)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main) //첫화면 표시
        binding = ActivityMainBinding.inflate(layoutInflater) //클래스 객체화
        val view = binding.root //객체화한 뷰
        setContentView(view) // 뷰를 메모리상으로 올림(화면 표시)

        binding.btnMain.setOnClickListener{ //클릭 이벤트 리스너
            var intent= Intent(this, SecondActivity::class.java) //인텐트 정의 (현재, 목적지)
            intent.putExtra("data",binding.edtMain.text.toString()) //인텐트에 데이터를 저장 (키-값 쌍)
            startActivity(intent) //목적지 액티비티에 인텐트 전달
        }
    }

}

 

binding 변수는 바인딩 클래스로 저장해서 activity_main.xml의 뷰에 접근하기 용이하게 한다.

그 후에 inflate 함수로 객체화 하여 실제 사용 가능한 상태로 만들고,

가장 최상단에 존재하는 뷰를 가지고 와서 화면에 출력한다.

 

그 아래는 버튼에 대한 이벤트 리스너로서, 버튼이 눌리면 작동되는 메소드 이다.

그 후는 인텐트를 정의하여서, 인텐트에 데이터를 저장한 뒤에 그 값을 넘기는 코드이다.

 

그럼 레이아웃 폴더에 activity_second.xml를 만들어서 다음과 같이 입력하자

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
    android:id="@+id/txt_second"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="받아온 데이터 보여주기"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"></TextView>
</androidx.constraintlayout.widget.ConstraintLayout>

해당 텍스트 뷰는 인텐트로 전해진 값을 보여줄 창이다.

 

그 후에 SecondActivity.kt 을 만들어서 다음과 같이 입력하자.

package com.example.second_week

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.example.second_week.databinding.ActivitySecondBinding

class SecondActivity : AppCompatActivity() {
    lateinit var binding:ActivitySecondBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivitySecondBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)

        binding.txtSecond.text = intent.getStringExtra("data") //아이디를 통해 해당 뷰에 접근 후 속성을 변경
    }
}

이전에 ActivityMain 과 비슷하지만 마지막 줄이 조금 다르다.

바인딩 클래스를 통해서 원하는 뷰를 해당 ID를 통해 접근하고, 그 아래에 존재하는 속성을 변경하는 예제이다.

 

이 이후에 실행하면 결과는 다음과 같다.

값을 입력하고 버튼을 누르면 다른 액티비티에서 그 값을 받아 출력하는 모습이다.


정리

1. 뷰바인딩을 통해 레이아웃의 각각의 뷰에 접근하기 용이해지고, 안정성이 좋아진다.

2. 인텐트를 통해 액티비티에 값을 전달 할 수 있다.

 

반응형
Comments