英文:Android Data Binding: Dependent Properties
Android 数据绑定:属性依赖
声明 替代手写依赖
Android Studio 2.3 正式版已经发布 ,现在我想谈一些你可能会在数据绑定中使用到的新特征. 其中一件很酷的事就是你可以创建属性依赖。
命名,命名,命名
假设在应用中,我用一个viewmodel
来表示用户。它会包含 first name
, last name
, user name
, 和 display name
. 当这些属性改变的时候,UI也应当跟着变化, 所以 我需要让它可以被观察。
public class User extends BaseObservable {
private String firstName;
private String lastName;
private String userName;
private Resources resources;
public User(Resources resources) {
this.resources = resources;
}
@Bindable
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
notifyPropertyChanged(BR.firstName);
notifyPropertyChanged(BR.displayName);
}
@Bindable
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
notifyPropertyChanged(BR.lastName);
notifyPropertyChanged(BR.displayName);
}
@Bindable
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
notifyPropertyChanged(BR.userName);
notifyPropertyChanged(BR.displayName);
}
@Bindable
public String getDisplayName() {
if (firstName == null) {
if (lastName == null) {
return userName;
} else {
return lastName;
}
} else if (lastName == null) {
return firstName;
} else {
return resources.getString(R.id.name,
firstName, lastName);
}
}
}
你可以看到在 display name
没有可以回退的地方。它只是检查其它的属性并且基于它们产生一个值。
在 User 类里,不管是 firstName
, lastName
, 还是 userNames
改变, displayName
都会被更新因为我已经在它们各自的 setter
方法中通知了。
这是一个常见的情景:一个属性依赖另一个属性。依赖的属性 (e.g. setFirstName())必须通知它的依赖属性改变,但是这并不好.
声明属性依赖
在 Android Studio 2.3,你可以声明一个可绑定的属性来依赖其他属性:
public class User extends BaseObservable {
//...
@Bindable
public String getFirstName() { ... }
public void setFirstName(String firstName) {
this.firstName = firstName;
notifyPropertyChanged(BR.firstName);
}
@Bindable
public String getLastName() { ... }
public void setLastName(String lastName) {
this.lastName = lastName;
notifyPropertyChanged(BR.lastName);
}
@Bindable
public String getUserName() { ... }
public void setUserName(String userName) {
this.userName = userName;
notifyPropertyChanged(BR.userName);
}
@Bindable({"firstName", "lastName", "userName"})
public String getDisplayName() { ... }
}
Bindable 注解使用一个可选的参数来声明这些依赖。 displayName
属性被声明依赖于 firstName, lastName, 和 userName 属性。不管这些属性有什么改变, displayName 都会被更新。
这些依赖完全是在生成的bingding
文件被估算的。那也意味着如果你附加一个 Observable
给 User
,当其它属性改变的时候,你不会得到一个给 displayName
的通知。
使用属性依赖可以帮助你清理viewModel
。当潜在的数据模型是相对标准化— 在多个属性里数据不是重复的 — viewmodel
是为了展示UI而定做的。 那意味着属性间会经常相互影响。
举个例子,想象一下你的UI展示一张账单,你的商店基于购买的总额给予折扣。这个折扣也可以基于总额的一部分。然后,如果你想根据发货的状态来更改折扣,只需要更新折扣属性,而不用更新状态属性。
属性依赖会帮助你使你的 viewmodel
稍微简洁一点并且更容易维护。
Thanks to Chet Haase.