【Android】android设置了数据绑定databinding,view不随着model变化而变化
今天在将项目从findViewById转到MVVM的databinding时,发现有的view绑定了数据,但是数据变了,view并不会跟着改变现场还原将用户信息的头像uri绑定到ImageView,理论上来说,userInfoAll.UserInfo.avatar发生了改变,就会调用load方法重新设置头像,但是并没有发生<layout xmlns:android="http://schem
今天在将项目从findViewById转到MVVM的databinding时,发现有的view绑定了数据,但是数据变了,view并不会跟着改变
现场还原
将用户信息的头像uri绑定到ImageView,理论上来说,userInfoAll.UserInfo.avatar发生了改变,就会调用load方法重新设置头像,但是并没有发生
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable name="userInfoAll" type="com.learning.reading.fragment.word.bean.UserInfoAll" />
</data>
... ...
<ImageView
android:id="@+id/iv_myinfo_head"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_margin="10dp"
android:background="@null"
app:imgUri="@{userInfoAll.UserInfo.avatar}"/>
... ...
@BindingAdapter("app:imgUri")
public static void load(ImageView imageView, String uri) {
if (TextUtils.isEmpty(uri)) return;
Glide.with(imageView.getContext())
.load(PICTURE_PATH + uri)
.placeholder(R.drawable.icon_head)
.error(R.drawable.icon_head)
.into(imageView);
}
原因分析
来看一下UserInfoAll的数据结构。
public class UserInfoAll {
private static UserInfoAll instance = new UserInfoAll();
public static synchronized UserInfoAll getInstance() {
if (instance == null)
instance = new UserInfoAll();
return instance;
}
public static void setData(UserInfoAll userInfoAll) {
instance.setUser(userInfoAll.user);
instance.setUserInfo(userInfoAll.userInfo);
}
private User user;
private UserInfo userInfo;
public UserInfoAll() {
user = new User();
userInfo = new UserInfo();
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
// ... 其余用户信息 ...
}
public UserInfo getUserInfo() {
return userInfo;
}
public void setUserInfo(UserInfo userInfo) {
this.userInfo = userInfo;
// ... 其余用户信息 ...
}
// 存储用户关键信息
public class User {
private long id; // 用户id
// ... 其余用户关键信息 ...
public User() {
this.id = -1;
// ... 初始化其余用户信息 ...
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
// 其余用户关键信息...getter...setter...方法
}
// 存储用户附属信息
public class UserInfo extends BaseObservable{
private String avatar; // 用户头像的url地址
// ... 其余用户信息 ...
public UserInfo() {
this.updateTime = "";
// ... 设置其余用户附属信息 ...
}
@Bindable
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
notifyPropertyChanged(BR.avatar);
}
// 其余用户附属信息...getter...setter...方法
}
UserInfoAll主要包含两个类,User.class 存储用户的关键信息,用户id、手机号等;UserInfo.class 存储用户附属信息,头像url、个人说明等。
因为整个APP只需要保存这一份用户信息数据,所以采用单例模式。
UserInfoAll赋值分为两步
- 打开APP进行数据绑定时是第一次getInstance,这时new了一个UserInfoAll,调用了默认的构造函数(分别new了一个User和new了一个UserInfo,调用了如代码所示的各自的构造函数)。
- 从服务器获取用户信息成功之后,会调用setData方法,重新给UserInfoAll的单例赋值。
看起来好像没有问题,但ImageView的数据确实没有刷新,问题只会出在上面两个步骤。
步骤一不会有问题,看步骤二。
步骤二传进来一个新的UserInfoAll对象,然后分别对单例的User和UserInfo进行赋值,这个赋值其实是将单例的这两个对象的引用,指向了新传进来的UserInfoAll的User和UserInfo,这个过程是没有调用UserInfo.setAvatar(Stirng)方法的
那么我们是不是可以猜测,databinding绑定的数据监听是通过set和get方法实现的(没看源码,猜的,你们有兴趣的自己去研究,搞懂了记得给我讲讲)步骤二对User和UserInfo的赋值实际上没有调用到UserInfo.setAvatar(Stirng)方法,所以监听器没有监听到变化,导致数据没有刷新?
修改代码
public class UserInfoAll {
private static UserInfoAll instance = new UserInfoAll();
public static synchronized UserInfoAll getInstance() {
if (instance == null)
instance = new UserInfoAll();
return instance;
}
public static void setData(UserInfoAll userInfoAll) {
instance.setUser(userInfoAll.user);
instance.setUserInfo(userInfoAll.userInfo);
}
private User user;
private UserInfo userInfo;
private String token;
public UserInfoAll() {
user = new User();
userInfo = new UserInfo();
token = "";
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user.setId(user.id);
// ... 其余用户信息 ...
}
public UserInfo getUserInfo() {
return userInfo;
}
public void setUserInfo(UserInfo userInfo) {
this.userInfo.setAvatar(userInfo.avatar);
// ... 其余用户信息 ...
}
// 存储用户关键信息
public class User {
private long id; // 用户id
// ... 其余用户关键信息 ...
public User() {
this.id = -1;
// ... 初始化其余用户信息 ...
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
// 其余用户关键信息...getter...setter...方法
}
// 存储用户附属信息
public class UserInfo extends BaseObservable{
private String avatar; // 用户头像的url地址
// ... 其余用户信息 ...
public UserInfo() {
this.updateTime = "";
// ... 设置其余用户附属信息 ...
}
@Bindable
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
notifyPropertyChanged(BR.avatar);
}
// 其余用户附属信息...getter...setter...方法
}
再试一下果然好了
更多推荐
所有评论(0)