본문 바로가기

Android

[Android] findViewById가 귀찮을 때

 Android 개발을 하다보면 각각의 뷰에 id를 붙이고 findViewById를 통해 뷰를 찾는게 귀찮을 때가 많습니다.

그럴 땐 Android에서 제공하는 라이브러리 DataBinding을 사용하면 편해집니다.

https://developer.android.com/topic/libraries/data-binding

 

데이터 결합 라이브러리  |  Android 개발자  |  Android Developers

데이터 결합 라이브러리   Android Jetpack의 구성요소 데이터 결합 라이브러리는 프로그래매틱 방식이 아니라 선언적 형식으로 레이아웃의 UI 구성요소를 앱의 데이터 소스와 결합할 수 있는 지원 라이브러리입니다. 레이아웃은 흔히 UI 프레임워크 메서드를 호출하는 코드가 포함된 활동에서 정의됩니다. 예를 들어 아래 코드는 findViewById()를 호출하여 TextView 위젯을 찾아 viewModel 변수의 userName 속성에 결합합니다. K

developer.android.com

 MVVM패턴과 ViewModel을 사용할 때 더욱 빛을 내는 라이브러리지만 findViewById 작업을 줄이는 것 만으로도 좋은 거 같습니다.

라이브러리 적용 방법 (* 예시 MainActivity)

app/build.gradle

apply plugin: 'com.android.application'

android {
    ...
    // 이 부분 추가 후 Sync Now
    dataBinding{
    	enabled = true
    }
    //
    ...
}

 

activity_main.xml

* 기존의 xml을 layout 태그로 감싸줍니다. (은근히 감싸 주는 과정이 귀찮습니다)

<?xml version="1.0" encoding="utf-8"?>
<layout>
    <androidx.coordinatorlayout.widget.CoordinatorLayout
    	xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    	<!-- layout을 구성하는 View들... -->
    ...
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

 

 

MainActivity.java

public class MainActivity extends AppCompatActivity {
    // layout 태그를 통해 생성된 Binding객체
    // 클래스의 이름은 layout xml의 이름을 따름, layout_activity -> ActivityMainBinding
    ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // setContentView(R.layout.activity_main);
        // 기존의 setContentView 대신 DataBindingUtil을 통해 setContentView 후 리턴 값으로
        // binding 객체를 받음
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    }
    ...
}

 

 다음과 같이 binding 객체를 얻은 후엔 binding.(View의 Id)로 View를 참조할 수 있습니다.

ex)

   <TextView id="@+id/txt" /> ==> binding.txt로 참조 가능합니다

   id에 ' _ ' 를 넣었을 경우(ex. txt_test) ==> binding.txtTest로 변환 됩니다.

 

setContentView를 사용하지 않고 binding을 얻고 싶을 때

recyclerView 등에서 layout file을 inflate 사용할 때에도 binding을 사용할 수 있습니다.

...
    // 기존 코드
    // View v = LayoutInflater.from(context).inflate(R.layout.item_test, viewgroup);
    // DataBinding 적용
    TestItemBinding binding = TestItemBinding.inflate(context);
    // RootView를 얻어야 할 때
    View v = binding.getRoot();
...

ViewBinding??

https://developer.android.com/topic/libraries/view-binding?hl=ko

 

뷰 바인딩  |  Android 개발자  |  Android Developers

뷰 바인딩 기능을 사용하면 뷰와 상호작용하는 코드를 쉽게 작성할 수 있습니다. 모듈에서 사용 설정된 뷰 바인딩은 모듈에 있는 각 XML 레이아웃 파일의 바인딩 클래스를 생성합니다. 바인딩 클래스의 인스턴스에는 상응하는 레이아웃에 ID가 있는 모든 뷰의 직접 참조가 포함됩니다. 대부분의 경우 뷰 바인딩이 findViewById를 대체합니다. 설정 안내 참고: 뷰 바인딩은 Android 스튜디오 3.6 Canary 11 이상에서 사용할 수 있습니다. 뷰 바인

developer.android.com

 위에서 말했던 것 처럼 DataBinding 라이브러리는 MVVM와 ViewModel을 함께 사용할 때 더 빛을 내고, 그러기 위해 만들어진 라이브러리입니다.

 그래서 Android는 오로지 findViewById를 대체하기 위한 ViewBinding 라이브러리를 만들어 주는 듯 합니다.

ViewBinding은  Android 스튜디오 3.6 Canary 11 이상에서만 작동한다고 합니다(현재 2020-02-21). 추후 정식 업데이트에 적용된다면 새로 포스팅을 하겠습니다. (사용법은 비슷한 듯 합니다.)