설정

 

사용하고자 하는 module의 build.gradle에 추가

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

 

사용

 

모듈에 뷰 결합을 사용하도록 설정되면 모듈에 포함된 각 XML 레이아웃 파일의 결합 클래스가 생성됩니다.

(루트 뷰에  tools:viewBindingIgnore="true" 속성이 포함된 경우 제외)

결합 클래스의 이름은 XML 파일의 이름을 카멜 표기법으로 변환하고 끝에 'Binding'을 추가하여 생성되며, 루트뷰와 ID가 있는 모든 뷰의 참조가 포함됩니다.

 

 

                 activity_main.xml           →     activityMainBinding

                 fragment_example.xml  →     FragmentExampleBinding

 

 

 

 

 

 

Activity

      

기존 

class MainActivity : AppCompatActivity() {
	private lateinit var viewExample: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        viewExample = findViewById(R.id.view_example)
    }
}

 

뷰 바인딩 방식

class MainActivity : AppCompatActivity() {
	private lateinit var viewExample: TextView

	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater) // 뷰 바인딩 초기화
        setContentView(binding.root) // setContentView에 뷰 바인딩의 루트 요소를 전달
        
        viewExample = binding.viewExample  //id도 camelCase로 대체하여 접근
	}
}

XML 레이아웃 파일의 결합 클래스 (ActivityMainBinding)에 포함된 정적 메서드 inflate()를 호출하여 인스턴스를 생성합니다. 해당 인스턴스의 루트 뷰를 setContentView에 전달하여 화면상의 활성 뷰로 만듭니다.

 

실제 사용할 때는 레이아웃 파일의 결합 클래스를 binding으로 받아와 binding.viewExample과 같이 접근하는 것이 용이할 것이다.

 

 

Fragment

 

기존

class MyFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_my, container, false)
    }
}

 

 

 

View Binding 방식

class MyFragment : Fragment() {

    private var _binding: FragmentMyBinding? = null
    private val binding get() = _binding!!

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

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding.textViewMessage.text = "Hello, this is the fragment!"
    }
}

 

Fragment 생명주기와 관련되어 간략하게 언급하면 프래그먼트는 뷰보다 오래 지속되기 때문에 OnDestoryView()에서 

ViewBinding을 해제하지 않으면 메모리 누수의 원인이 됩니다.

 

추가적으로 참조 해제를 위한 _binding 변수는 nullable로 설정하고, 실제 뷰들에 대한 참조를 담고 있는 binding 변수는 non-nullable타입으로 설정하여 안전한(Null-Safe) 패턴을 적용하는 것이 권장됩니다.

 

 

 

 

findViewById와의 차이점

  • Null-Safety      :     뷰 결합은 뷰의 직접 참조를 생성합니다. 유효하지 않은 뷰 ID로 인해 null 포인터 예외가 발생할 위험이 없습니다. 
  • Type-Safety     :    각 바인딩 클래스에 있는 필드의 유형이 XML 파일에서 참조하는 뷰와 일치합니다. 즉, type casting에 있어 예외가 발생할 위험이 없습니다.

 

 


 

 

해당 글은 다음을 참조하여 공부한 내용을 정리한 글입니다.

 

 

뷰 결합  |  Android 개발자  |  Android Developers

 

뷰 결합  |  Android 개발자  |  Android Developers

뷰 결합 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 뷰 결합 기능을 사용하면 뷰와 상호작용하는 코드를 쉽게 작성할 수 있습니다. 모듈에서 사용 설정

developer.android.com

 

 

+ Recent posts