본문

160319A(토)

Android MVVM & DataBinding


Android Data Binding Guide

http://developer.android.com/intl/ko/tools/data-binding/guide.html


1. The Data Binding Library offers both flexibility and broad compatibility(적합성, 일치성)

Android 2.1 (API level 7+).

Gradle 1.5.0-alpha1 or higher


2. build.gradle file in the app module.

android {
   
....
    dataBinding
{
        enabled
= true
   
}
}


3. Android Studio 1.3 and later


XML Layout

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
   
<data>
       
<variable name="user" type="com.example.User"/>
   
</data>

   
<LinearLayout
       
android:orientation="vertical"
       
android:layout_width="match_parent"
       
android:layout_height="match_parent">
       
<TextView android:layout_width="wrap_content"
           
android:layout_height="wrap_content"
           
android:text="@{user.firstName}"/>
       
<TextView android:layout_width="wrap_content"
           
android:layout_height="wrap_content"
           
android:text="@{user.lastName}"/>
   
</LinearLayout>
</layout>


@{user.firstName}

public class User {
   
private final String firstName;
   
private final String lastName;
   
public User(String firstName, String lastName) {
       
this.firstName = firstName;
       
this.lastName = lastName;
   
}
   
public String getFirstName() {
       
return this.firstName;
   
}
   
public String getLastName() {
       
return this.lastName;
   
}
}


Binding Data

Binding class will be generated based on the name of the layout file


ex)

main_activity.xml -> MainActivityBinding.class


MainAcitvityBinding 클래스는 레이아웃의 모든 property를 바인딩 해놓으며, 

binding expression의 값을 할당하는 방법을 알고있다.


The easiest means for creating the bindings is to do it while inflating:

@Override
protected void onCreate(Bundle savedInstanceState) {
   
super.onCreate(savedInstanceState);
   
MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
   
User user = new User("Test", "User");
   binding
.setUser(user);
}


Case RecyclerView adapter :

ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
//or
ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);


Binding Events

attribute 명명 규칙

View.OnLongClickListener

onLongClick()


XML

android:onLongClick


Layout Details

Import

<data>
   
<import type="android.view.View"/>
</data>
<TextView
   
android:text="@{user.lastName}"
   
android:layout_width="wrap_content"
   
android:layout_height="wrap_content"
   
android:visibility="@{user.isAdult ? View.VISIBLE : View.GONE}"/>


Data Objects

The real power of data binding can be used by giving your data objects the ability to notify when data changes. 


1. Obervable Objects

BaseObservable, was created to implement the listener registration mechanism.

The data class implementer is still responsible for notifying when the properties change.

This is done by assigning aBindable annotation to the getter and notifying in the setter.

private static class User extends BaseObservable {
   
private String firstName;
   
private String lastName;
   
@Bindable
   
public String getFirstName() {
       
return this.firstName;
   
}
   
@Bindable
   
public String getLastName() {
       
return this.lastName;
   
}
   
public void setFirstName(String firstName) {
       
this.firstName = firstName;
       notifyPropertyChanged
(BR.firstName);
   
}
   
public void setLastName(String lastName) {
       
this.lastName = lastName;
       notifyPropertyChanged
(BR.lastName);
   
}
}

@Bindable annotation 은 BR 클래스 파일을 컴파일중에 만든다.


Custom Setters

@BindingAdapter("android:paddingLeft")
public static void setPaddingLeft(View view, int padding) {
   view
.setPadding(padding,
                   view
.getPaddingTop(),
                   view
.getPaddingRight(),
                   view
.getPaddingBottom());
}
@BindingAdapter({"bind:imageUrl", "bind:error"})
public static void loadImage(ImageView view, String url, Drawable error) {
   
Picasso.with(view.getContext()).load(url).error(error).into(view);
}
<ImageView app:imageUrl=“@{venue.imageUrl}”
app:error=“@{@drawable/venueError}”/>
@BindingAdapter("android:onViewAttachedToWindow")
public static void setListener(View view, OnViewAttachedToWindow attached) {
    setListener
(view, null, attached);
}

@BindingAdapter("android:onViewDetachedFromWindow")
public static void setListener(View view, OnViewDetachedFromWindow detached) {
    setListener
(view, detached, null);
}

@BindingAdapter({"android:onViewDetachedFromWindow", "android:onViewAttachedToWindow"})
public static void setListener(View view, final OnViewDetachedFromWindow detach,
       
final OnViewAttachedToWindow attach) {
   
if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB_MR1) {
       
final OnAttachStateChangeListener newListener;
       
if (detach == null && attach == null) {
            newListener
= null;
       
} else {
            newListener
= new OnAttachStateChangeListener() {
               
@Override
               
public void onViewAttachedToWindow(View v) {
                   
if (attach != null) {
                        attach
.onViewAttachedToWindow(v);
                   
}
               
}

               
@Override
               
public void onViewDetachedFromWindow(View v) {
                   
if (detach != null) {
                        detach
.onViewDetachedFromWindow(v);
                   
}
               
}
           
};
       
}
       
final OnAttachStateChangeListener oldListener = ListenerUtil.trackListener(view,
                newListener
, R.id.onAttachStateChangeListener);
       
if (oldListener != null) {
            view
.removeOnAttachStateChangeListener(oldListener);
       
}
       
if (newListener != null) {
            view
.addOnAttachStateChangeListener(newListener);
       
}
   
}
}













'Mobile > Android' 카테고리의 다른 글

160326P(토)  (0) 2016.03.26
160321A(월)  (0) 2016.03.21
160302P(수)  (0) 2016.03.03
160210P(수)  (0) 2016.02.11
160119P(화)  (0) 2016.01.19

공유

댓글