ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [AAC] DataBinding 1- 데이터바인딩 기본 사용법
    Android/ArchitectureComponent 2021. 9. 9. 18:45

    Activity에 연결된 layout 파일의 View를 참조하기 위해서 findViewById를 사용하였다.

    findViewById는 동일한 이름의 ui component id가 존재할 때 다른 view의 id가 들어갈 여지가 있고

    id를 찾는데 시간이 오래걸린다. 가독성 또한 좋지않다. 

     

    ViewBinding은 layout파일과 관련된 바인딩 오브젝트를 생성하여 바인딩 오브젝트를 통하여 id에 해당하는 뷰를 참조할 수 있었다.

     

    DataBinding은 ViewBinding의 확장 개념으로 ViewBinding의 기능을 포함해

    layout파일에서 변수처럼 사용할 수 있는 변수를 포함시켜 바인딩 오브젝트에 데이터를 멤버로 포함시킬 수 있다.

    바인딩 오브젝트에 포함된 변수를 이용하여 layout부분에서 ui의 값을 설정할 수도 있으며

    코드상 변수에 값을 대입할 수 있다.

     

    또한 ViewModel, LiveData와 같이 사용하여 효율적인 ui처리를 할 수 있게 되는 것 같다. 


    • dependency추가 및 설정

    간단한 테스트를 하기 위해 layout을 다음과 같이 변경하자.

     

    activity_main.xml

     

    사용자 정의 클래스 생성


    • layout파일을 <layout></layout> 태그로 감싼 후 namespace를 layout태그로 이동시킨다.

    activity_main.xml

    루트태그를 layout태그로 감쌌기 때문에 이제 activity_main.xml에 해당되는 데이터 바인딩 클래스를 사용할 수 있다.

     

    생성되는 바인딩 클래스의 이름

    test_test2.xml -> TestTest2 + Binding -> TestTest2Binding으로 사용이 가능하다.

    activity_main.xml -> ActivityMainBinding 

     

    데이터 바인딩은 뷰 바인딩의 확장 기능이므로 바인딩된 뷰 또한 참조할 수 있다.

    root뷰는 id를 설정하지 않아도 항상 바인딩 오브젝트.getRoot를 통하여 참조가 가능하다.

    id가 지정된 view에 한해 참조가 가능하다. 


    • DataBinding클래스의 멤버로 포함될 변수 추가하기

    이전까지의 단계에 그치면 ViewBinding의 기능밖에 해당되지 않는다. ui값 변경에 필요한 변수를 layout에서 선언하자.

    <data><variable.../></data>태그 를 추가한다.

     

    activity_main.xml

    <data>태그는 생성되는 바인딩 클래스의 멤버로 포함될 변수를 선언하기 위한 부모 태그이다.

    자식 태그 <varaiable>을 통하여 변수를 추가할 수 있다.

    클래스 타입 변수, primitive 타입 변수 모두 가능하다.

     

    layout의 <data>태그 내부에 추가된 <variable>은

    바인딩 클래스의 멤버로서 사용될 수 있다.( 코드쪽에서도 사용될 수 있다 )

    또한 바인딩 클래스의 멤버를 layout의 view와 결합 할 수 있다.( layout expression인데 layout쪽에서도 사용가능 )

     

    • DataBinding 오브젝트를 사용

    데이터 바인딩 클래스를 사용하기 위해서는 액티비티의 setContentView를 변경해줘야한다.

    inflate를 통한 방법도 있으니 따로 공부해볼것

    데이터 바인딩 클래스의 인스턴스가 binding에 대입되고 binding변수를 통해 뷰를 가져올수 있으며 

    <data>안에서 선언한 변수도 사용할 수 있다. 

     

    DataBinding 파트에 대한 내용이지만 ViewBinding내용을 잠깐 보고 넘어간다.

    앱 실행


    이전에 만든 MyClass를 통해 이쁘게 ViewBinding을 사용해보자.

    ui와 관련된 데이터가 변경된다면 일일이 코드상으로 변경된 데이터를 setText를 통해 넣어줘야 하는 문제점이 발생

    데이터 바인딩클래스의 멤버와 view에 설정될 값을 layout파일에서 바인딩 시켜보자.( 데이터 바인딩 ) 

     

    layout expression을 통해 view의 속성에 바인딩 시킬 수 있다.

    https://developer.android.com/topic/libraries/data-binding/expressions?hl=en 

    데이터 바인딩 클래스의 MyClass타입 변수 myClass의 property들을 각각의 TextView의 text속성에 바인딩 하였다.

    @{}는 layout expression인데 이를 통해 layout에 바인딩 변수를 설정하고 나중에 layout이 인플레이팅되어 뷰가 될때 속성 값들이 적용된다.

     

    메인액티비티에서 바인딩 클래스의 myClass 변수에

    MyClass인스턴스를 대입하면 textView의 text값이 자동으로 변경되게 된다.

    Avoiding null pointer exceptions

    바인딩된 코드는 자동으로 null check를 진행하여 NullPointerException을 피할 수 있다.

    바인딩 클래스의 변수 myClass가 null일 경우 String 프로퍼티는 기본값으로 null로 들어가고 , Int프로퍼티인 경우 기본값 0이 들어간다.

    다음과 같이 바인딩 클래스의 myClass변수에 인스턴스를 할당하지 않으면 화면에 아무것도 출력되지 않게 된다.

    MyClass 클래스의 age는 생성자 매개변수이지 프로퍼티가 아니였다.

    프로퍼티에 해당하는 name, stringAge모두 String이라 null이 대입되기 때문에 0또한 화면에 출력되지 않는다.

     

    데이터 바인딩을 잘 사용하기 위해서는 layout expression을 자세하게 공부해야 할 것 같다.


    • View로부터 디스패치된 이벤트 처리를 데이터 바인딩을 통해 처리할 수 있다.

    Event attribute names are determined by the name of the listener method with a few exceptions. For example, View.OnClickListener has a method onClick(), so the attribute for this event is android:onClick.

    View의 이벤트 속성은 리스너 인터페이스에 해당하는 메서드의 이름으로 결정된다. 

    클릭 이벤트의 경우 android: onClick이 된다.


    데이터 바인딩을 통해 이벤트를 핸들링 하는 두가지 메커니즘

     

    1. Method References

     

    리스너 메서드의 시그니쳐(인자개수,인자순서,인자타입, 리턴타입) 에 맞는 메서드의 참조를 넣을 수 있다. 

    (추가적으로 메서드의 참조를 넣기 때문에 메서드의 이름은 상관없다)

    해당되는 메서드와 리스너 인스턴스를 묶어 타겟 뷰에 리스너를 설정한다.

    layout expression이 null로 평가될 경우, 데이터 바인딩은 리스너 인스턴스를 만들지 않고 null인 리스너를 등록한다.

     

    MyClass클래스

    activity_main.xml

     

    android: onClick속성에 myClass의 myOnClick메서드 참조를 ::를 통해 넣어줬다.

     

    MainActivity.kt

    메서드 참조를 넣을 때는 시그니쳐를 꼭 맞춰야하기 때문에 myOnClick메서드의 파라메터에 view:View를 꼭 선언해야한다.

     


    2. Listener Bindings

     

    이번 테스트를 해보니 에러가 발생하였습니다. Button에 id를 꼭 설정해주세요

     

    람다 표현식을 이용하는 경우이다. 이벤트가 발생했을 때 람다표현식이 평가된다. 

    바인딩에 포함된 <variable>들을 자유롭게 이용하여 layout-expression을 통하여 람다 표현식 만들 수 있다는 점이 코드쪽에서 구현되는 Method Reference와의 큰 차이이다. 

    (1번인 function reference는 코드쪽에서 구현된 메서드 로직을 넣을 때 적당하고, 2번인 Listener binding의 경우 다양한 <variable>들을 통해 로직을 만들 수 있다. 또한 밑에서 보겠지만 이 변수들을 코드쪽의 메서드 인자로 넘겨줄 수 있다.)

     

    Method Reference를 이용했을 때는 참조로 넣어줄 메서드는

    리스너에 해당하는 메서드와 시그니쳐가 완전히 동일해야 했다.

     

    Listener Binding의 경우에는 시그니쳐가 일치할 필요없이 return 타입만 일치하면 된다.

    리스너 메서드의 return타입과 람다표현식 구현부 함수의 return타입만 맞으면 된다.

     

     

    View파라메터는 어디로 갔는지에 대해서 한참 헤맸다.... 

    람다 표현식 문법과 layout expression의 람다와 문법 차이가 있던 것도 한몫했다. 또한 View인자를 생략가능한 것도 있어서 그렇다....

    val t : (Int,Int)->Int = {i1 : Int, i2 : Int-> i1+i2 }

    람다 표현식의 { } 부분을 통해 다음과 같이 작성해야 할 줄 알았다. layout expression( @{} ) 은 조금 다르다.

    파라메터는 무조건 View하나만 정의할 수 있다. 또한 생략이 가능하다.

    View의 참조가 자동으로 넘어오기 떄문에 받을 파라메터만 설정한다. 타입설정은 포함되면 안된다.

    전달된 참조를 view를 통해 사용하는 것이다. myView로 설정하면 myView로 뷰참조를 사용할 수 있다.


    전달된 View 참조를 view를 통해 람다식의 바디에서 사용할 수 있다.

    myOnClick2()의 인자에서도 사용가능하다. 그러나 현재 구현된 myOnClick2()는 View를 인자로 받지 않고 있기때문에

    넣어주면 앱 빌드시 에러가 발생한다.( ide가 빨간줄은 안쳐준다. 빌드과정에서 발견됨)

     

    이름은 다른 것으로 사용해도 된다.


    myOnClick2메서드에서 View참조를 받기만 하지 myOnClick2메서드에서 사용되지 않고 있다.

    이러한 경우 파라메터에서 받지 않을 수 있다.


    myOnClick2에서 View의 참조를 사용해야 할 경우 View를 파라메터로 설정하고 람다식 바디에서도 view를 받아야 한다.


    데이터 바인딩 변수를 넘겨줄수도 있다.

    람다식에 넘기기 위한 데이터 바인딩 변수 testInt

     

     

    Button의 id와,  default값인 0으로 i가 출력된다(액티비티 코드에서 testInt를 초기화하지 않았으므로)

     

    본 테스트에서는 MainActivity.kt에서 항상 binding인스턴스의 myClass변수에 MyClass인스턴스를 넣어줘야한다.


    이해가 어렵다면 다음과 비슷하게 구현된다고 보면된다. 



     

    다음 포스팅- inflate, bind, setContentView에 대해

    2021.09.11 - [Android/DataBinding] - [Android] DataBinding 2 - generated binding class

    댓글

Designed by Tistory.