본문
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 |
댓글