[Android/Kotlin] ViewBinding 뷰 오브젝트 접근 (findViewById 대체)

Notepad96

·

2022. 8. 17. 23:55

300x250

 

 

1. 요약

 

결과

 

이 글에서는 ViewBinding을 통하여 간편하게 View Object들의 접근하여 Click Event를 설정하거나 TextView의 Text를 변경하는 방법을 기술한다.

 

이를 위해서는 우선 App 수준 gradle 파일에서 ViewBinding을 사용하도록 설정해주어야 한다.

 

이는 기존 findViewById 혹은 deprecated 된 kotlin extensions plugin을 사용하여서 View에 접근하였던 방법들과 비교하여 View의 접근 속도가 느리거나 null-safe하지 못하는 단점들을 대체할 수 있는 좋은 방안이다.

 

 

 

 

2. 레이아웃

 

2-1. activity_main.xml

메인 레이아웃으로 View Object들의 접근하여 클릭 이벤트를 설정하거나 텍스트 값을 변경되는지 확인하기 위하여 Button 1개와 TextView 1개 Fragment 1개로 구성하였다.

 

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"
    android:gravity="center"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/Btn01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Activity Button" />

    <TextView
        android:id="@+id/Text01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Activity"
        android:textSize="22sp" />

    <fragment
        android:id="@+id/fragment01"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.notepad96.viewbinding.BlankFragment"
        />


</LinearLayout>

 


 

2-2. fragment_blank.xml

프레그먼트를 사용할 경우 ViewBinding 변수를 초기화하는 방법이 다르기 때문에 추가한 Fragment의 레이아웃이다.

레이아웃은 이벤트 설정 및 값 변경이 잘 되는지 확인하기 위하여 메인 레이아웃과 동일하게 Button 1개와 TextView 1개로 구성하였다.

 

fragment_blank.xml

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:background="#ccc"
    android:gravity="center"
    tools:context=".BlankFragment">

    <Button
        android:id="@+id/Btn02"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment Button" />

    <TextView
        android:id="@+id/Text02"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment"
        android:textSize="22sp" />


</LinearLayout>

 

 

 

 

3. 코드 및 설명

 

3-1. build.gradle (app)

우선 ViewBinding을 사용하기 위해서 build.gradle 파일서 사용한다고 설정해주어야 한다.

 

아래처럼 "buildFeatures.viewBinding = true"를 설정 후 Sync Now를 해주면 ViewBinding 사용이 가능해진다.

 

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
}

android {
	// Android Studio 버전 4.0 이상
    buildFeatures.viewBinding = true
    
    // Android Studio 버전 4.0 미만
    viewBinding.enabled = true

    compileSdk 31

    defaultConfig {
    ......

 


 

3-2. MainActivity.kt

코드를 확인하면 binding 변수를 선언해준 후 초기화해주는 것을 확인할 수 있다.

 

변수의 타입을 보면 ActivityMainBinding으로 이는 "Layout의 xml 파일 이름 + Binding이 붙은 형태"로서 activity_main.xml 뷰의 접근하기 위한 것이기 때문의 파일명인 ActivityMain + Binding이라는 타입으로 만들어지는 것이다.

 

View 오브젝트들의 접근하기 위해서는 "binding.[View Object ID 값]"으로 접근이 가능하다.

 

+) 여기서 사용한 by lazy는 객체가 null일 경우 해당 값으로 초기화하도록 하는 방법이다.

 

package com.notepad96.viewbinding

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.notepad96.viewbinding.databinding.ActivityMainBinding

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

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        binding.Btn01.setOnClickListener {
            binding.Text01.text = "Change Text"
        }
    }
}

 


 

3-3. BlankFragment.kt

Fragment일 경우에는 Activity일 경우와 binding을 초기화해주는 방법이 다르다. 그 외에 타입명을 지정하고 binding을 통하여 id를 통해 접근하는 방식은 동일하다.

 

(여기서는 Layout 이름이 fragment_blank 이므로 타입이 FragmentBlankBinding이 된다.)

 

 

package com.notepad96.viewbinding

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.notepad96.viewbinding.databinding.FragmentBlankBinding

class BlankFragment : Fragment() {
    private lateinit var binding: FragmentBlankBinding

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentBlankBinding.inflate(inflater, container, false)

        binding.Btn02.setOnClickListener {
            binding.Text02.text = "Change Text"
        }

        return binding.root
    }

}

 

 

 

 

4. 전체 파일

 

 

GitHub - Notepad96/BlogExample02

Contribute to Notepad96/BlogExample02 development by creating an account on GitHub.

github.com

 

 

300x250