반응형
※ findViewById()메소드를 이용한 View참조 방법이 가진 문제를 해결하기 위한 기법들[코드의 번거로움과 메소드의 동작속도 문제]

1. ButterKnife 외부 라이브러리 사용하기 (버터 나이프 라이브러리)
2. ViewBinding 안드로이드 아키텍처 구성요소
3. DataBinding (view binding + data binding) : 뷰결합 + 데이터 결합 기능까지 가진 아키텍처 구성요소

 

이전 글에서 소개했던 ButterKnife 라이브러리는 구글 안드로이의 고유 기능 SDK 가 아닙니다. 그렇기에 언제나 문제없이 안전하게 사용하기에는 제약이 있다고 볼 수도 있습니다. 물론. 지금까지 큰 문제 없이 잘 사용되어 왔었기에 앞으로도 충분히 그러하리라 예상되기는 합니다. 다만, @어노테이션을 통한 작업은 생각보다 조금 귀찮은 추가 작업이고 뷰들이 많아지면 그만큼 @Bind 어노테이션이 늘어나고 액티비티의 필드(멤버변수) 위치에 여러줄의 참조변수를 만드는 작업이 필요합니다. 은근히 귀찮고 지저분합니다.

 

버터나이프에 대해 좀더 알아보고 싶으신 분은 이전 글을 보고 오시기 바랍니다.

2021.09.13 - [소소한 소스코드] - [안드로이드 Android] Butter Knife (버터나이프) 라이브러리
 

[안드로이드 Android] Butter Knife (버터나이프) 라이브러리

안드로이드 앱을 개발하면서 가장 많이 사용하게 되시는 메소드 중 하나가 findViewById() 입니다. 안드로이드 앱개발에서 화면 UI는 xml언어를 사용하고 컨트롤을 위한 코드는 자바 or 코틀린 언어를

kitesoft.tistory.com


이번에 소개할 뷰 바인딩(view binding)은 안드로이드 아키텍처 구성요소로서 앱 모듈별로 설정하여 사용할 수 있는 기능입니다.

뷰 바인딩 기능을 사용하면 뷰를 제어하는 코드를 쉽게 작성할 수 있습니다. 

 

뷰 바인딩과 실습에 대한 소개는 코드의 주석으로 설명을 좀 더 간략하게 소개하니 아래 글이 복잡하다면 그냥 바로 코드만 보셔도 됩니다.

 

뷰 바인딩의 가장 큰 특징은,  레이아웃 xml 파일와 연결되는 바인딩 클래스가 자동으로 설계되어 만들어지고 그 클래스의 멤버로서 레이아웃 xml에 ID가 있는 모든 뷰를 참조하는 참조변수가 포함되어 있다는 겁니다. 그렇기에 별도의 findViewById()를 하지 않아도 이 바인딩 클래스의 객체(인스턴스)안에 모든 뷰들의 참조변수가 만들어져 있기에 그냥 사용하기만 하면 됩니다. 백마디 말보다 한번 코드를 보면 더 이해하기 좋을 겁니다. 

 

뷰바인딩 기능에 의해 레이아웃 xml 파일와 연결되는 바인딩 클래스는 자동으로 만들어지기에 그 이름이 특정한 규칙에 맞게 명명되어 만들어집니다. 딱 봐도 어떤 xml과 연결되었는지 바로 알 수 있는 이름입니다. 몇가지 예로 확인해보겠습니다.

 

ex.1) 액티비티 레이아웃 파일명과 자동으로 만들어지는 바인딩 클래스명 
activity_main.xml --> ActivityMainBinding 
activity_second.xml --> ActivitySecondBinding
activity_xxx.xml --> ActivityXxxBinding 

ex.2) 프레그먼트 레이아웃 파일명과 자동으로 만들어지는 바인딩 클래스명 
fragment_my.xml --> FragmentMyBinding 
fragment_login.xml --> FragmentLoginBinding 
fragment_xxx.xml --> FragmentXxxBinding 

ex.3) 리사이클러뷰(아답터뷰)의 아이템 1개 레이아웃 파일명과 자동으로 만들어지는 바인딩 클래스명 
recycler_item.xml --> RecyclerItemBinding 
recycler_xxx.xml --> RecyclerXxxBinding

 

 

뷰 바인딩 역시 ButterKinfe 라이브러리처럼 뷰 참조를 간단히 하여 제어하는 기능이기에 예제 실습을 버터나이프와 거의 똑같은 순서로 진행하고자 합니다. 그래서 간단하게 액티비티에서 보여주는 TextView의 글씨를 변경하는 실습부터, Fragment에서 뷰 바인딩 하기와 마지막으로 RecyclerView의 ViewHolder에서 뷰바인딩을 적용하는 모습을 순서대로 소개하고자 합니다.

 

이전 버터나이트에서는 모든 실습을 하나의 포스트에 모두 작성하였는데 너무 길어서 보기도 힘들고 글쓰기도 어려워서 실습단계별로 글을 나누어 1)~5) 실습을 5개의 포스트로 나누어 소개하고자 합니다.

 

1) 먼저 간단하게 TextView 1개를 만들고 이를 뷰 바인딩으로 참조하여 글씨 변경 해보기

 

■ 뷰 바인딩 사용 설정

ViewBinding 외부 라이브러리가 아니고 안드로이의 아키텍처 구성요소이기에 사용설정을 (모듈단위)build.gradle 에서 해주면 됩니다.

※ Android Studio 4.0 버전 이전과 이후가 다르니 주의 하시면서 주석 // ##  부분을 주의깊게 보시고 적용하시기 바랍니다. 현재 안드로이드 개발자 사이트의 문서에서는 4.0버전 이전에서의 코드가 소개되고 있으니 주의하세요.

# build.gradle(Module:app)
plugins {
    id 'com.android.application'
}

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"

    defaultConfig {
        applicationId "com.mrhi2021.ex98viewbinding"
        minSdkVersion 23
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    // ## ViewBinding 사용 설정 ######################
    //Android Studio 버전 4.0 이상
    buildFeatures {
        viewBinding = true
    }

    //Android Studio 버전 4.0 이전일 경우 - [3.6이전에서는 뷰바인딩 사용불가]
//    viewBinding {
//        enabled = true
//    }
    // ##############################################
}

dependencies {

    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

 

 

- 레이아웃파일과 액티비티자바 파일을 보겠습니다. 상세설명은 주석을 반드시 참고해 주시기 바랍니다.

# 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:padding="16dp"
    tools:context=".MainActivity">

    <!-- 1) 기본 TextView  -->
    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="8dp"
        android:textColor="#FF333333"
        android:text="Hello"/>

</LinearLayout>

 

# MainActivity.java
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

import com.mrhi2021.ex98viewbinding.databinding.ActivityMainBinding;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    // findViewById() 메소드를 이용한 View 참조 방법이 가진 문제를 해결하기 위한 기법들 [ 코드의 번거로움과 메소드의 동작속도 문제 ]
    // 1. ButterKnife 외부 라이브러리 사용하기
    // 2. ViewBinding 안드로이드 아키텍처 구성요소
    // 3. DataBinding (view binding + data binding) : 뷰결합 + 데이터 결합 기능까지 가진 아키텍처 구성요소

    // 이번 실습에서는 뷰 참조만 관점으로 볼때 가장 성능이 좋은 ViewBinding 안드로이드 아키텍처 구성요소 예제 소개
    // ButterKnife의 어노테이션을 이용한 BindView 역시 코드가 간결하다고 볼수없음. 이를 개선하였다고 보면 됨.

    // ViewBinding은 외부 라이브러리가 아니고 안드로이의 아키텍처 구성요소이기에 사용설정을 (모듈단위) build.gradle 에서 해주면 됨.

    // 뷰바인딩 기능의 주요특징은 xml 레이아웃파일(activity_main.xml)의 뷰들을 이미 연결(Bind)하고 있는 클래스가 자동으로 만들어져서
    // 개발자가 직접 뷰 참조변수를 만들어서 findViewBy()로 찾아서 연결하는 일련의 모든 작업을 할 필요가 없게 만들어 놓은 기능임.

    // 이때, 자동으로 xml 레이아웃 파일의 뷰들의 id와 같은 이름을 가진 멤버변수를 가진 클래스는 그 이름이 규칙적으로 명명되어 만들어짐.
    // 레이아웃파일의 이름에 맞게 클래스이름이 만들어짐.

    // ex.1) 액티비티 레이아웃 파일명과 자동으로 만들어지는 바인딩 클래스명
    // activity_main.xml      -->   ActivityMainBinding
    // activity_second.xml    -->   ActivitySecondBinding
    // activity_xxx.xml       -->   ActivityXxxBinding

    // ex.2) 프레그먼트 레이아웃 파일명과 자동으로 만들어지는 바인딩 클래스명
    // fragment_my.xml        -->   FragmentMyBinding
    // fragment_login.xml     -->   FragmentLoginBinding
    // fragment_xxx.xml       -->   FragmentXxxBinding

    // ex.3) 리사이클러뷰(아답터뷰)의 아이템 1개 레이아웃 파일명과 자동으로 만들어지는 바인딩 클래스명
    // recycler_item.xml      -->   RecyclerItemBinding
    // recycler_xxx.xml       -->   RecyclerXxxBinding


    // 실습방법은 이전에 실습했던 ButterKnife와 완전히 동일하게 진행해 봄으로서 차이점을 극명하게 확인.

    //1) 먼저 간단하게 TextView 1개를 만들고 이를 뷰 바인딩으로 참조하여 글씨 변경해 보기
    // - ViewBinding 초기화 -
    // 액티비티의 onCreate()에서 액티비티가 직접 setContentView()를 하지 말고 뷰바인딩 클래스가 레이아웃파일을 inflate해서 만들고 참조하여 멤버변수로 가지는 객체를 생성

    // activity_main.xml 파일과 연결되어 있는 바인딩 클래스 참조변수
    ActivityMainBinding mainBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //액티비티가 직접 setContentView()로 뷰들을 생성하지 않도록... 주석처리
        //setContentView(R.layout.activity_main);

        // xml 레이아웃파일명과 관련되어 뷰바이딩 기능에 의해 자동으로 설계되어진 클래스을 이용하여 뷰들의 id와 같은 이름을 가진 참조변수를 멤버로 가지는 객체 생성
        //activity_main.xml과 연결되는 바인딩클래스인 ActivityMainBinding 클래스의 inflate() static 메소드를 통해 뷰를 바인딩클래스가 직접 생성(inflate)
        // 바인딩 클래스의 멤버로 여러 뷰들의 참조변수들이 있으므로 가급적 바인딩클래스의 참조변수는 이 액티비티클래스의 멤버변수 위치를 만들것을 권장함.
        mainBinding= ActivityMainBinding.inflate(getLayoutInflater()); //파라미터로 LayoutInflater객체 전달

        //이 액티비티가 보여줄 내용물 뷰를 바인딩 클래스 객체의 최상위 뷰(rootView : activity_main.xml의 첫번째 레이아웃 뷰 - 이 예제에서는 LinearLayout)로 설정
        setContentView(mainBinding.getRoot());

        //1) TextView 글씨 변경하기
        //이미 activity_main.xml의 뷰들을 참조하여 연결하고 있는 바인딩 클래스인 ActivityMainBinding의 객체인 mainBinding의 멤버변수로
        //각 뷰들의 id 값과 이름이 완전 똑같은 해당뷰의 참조변수들이 찾아져서 연결되어 있는 상태임.
        mainBinding.tv.setText("Nice to meet you. ViewBinding");
    }
   
}

뷰가 TextVeiw 1개여서 아직은 뷰 바인딩이 더 코드가 간결한 건지 잘 안느껴지실 수 있습니다. 다음 실습을 따라하시면서 얼마나 좋은 점점 알아가시게 될겁니다.

 

다음 글에서는 버튼을 클릭하여 글씨를 변경하는 코드를 뷰 바인딩으로 제어해 보겠습니다.

반응형

+ Recent posts