如何在数据绑定库中通知视图?

时间:2017-02-05 10:18:01

标签: android observer-pattern android-databinding

您好我的问题是我的活动正在监听viewmodel字段更改,但回调未被调用!

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
    binding.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
        @Override
        public void onPropertyChanged(Observable observable, int i) {
            Log.d(getClass().getSimpleName(), "changed");
        }
    });
    User user = new User("user");
    binding.setUser(user);
    user.setName("newUser");
    }

}

和我的viewModel:

public class User extends BaseObservable {

public String name;

public User(String name) {
    this.name = name;
}

@Bindable
public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
    notifyPropertyChanged(BR.name);
}

}

UI已更新,但未调用回调。我想要一个回调加UI更新。 我想知道数据绑定库是这样的!

这里有像Rxjava这样的图书馆,但我不想进口它。

2 个答案:

答案 0 :(得分:3)

执行此操作时:

ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
binding.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
    @Override
    public void onPropertyChanged(Observable observable, int i) {
        Log.d(getClass().getSimpleName(), "changed");
    }
});
User user = new User("user");
binding.setUser(user);
user.setName("newUser");

您应该收到一封关于您提供的回调的通知,并且应该在您致电binding.setUser(user)时收到。查找ActivityMainBinding.java,您将在应用的构建文件夹中看到为该类生成的代码。在setUser()方法中,您会看到呼叫notifyPropertyChanged(BR.user)的呼叫,该呼叫将呼叫您的听众。

您遇到的问题是您想要的数据更改(名称)发生在用户而不是绑定上。要获得有关用户更改的通知,您必须添加这样的列表:

ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
User user = new User("user");
user.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
    @Override
    public void onPropertyChanged(Observable observable, int i) {
        Log.d(getClass().getSimpleName(), "changed");
    }
});
binding.setUser(user);
user.setName("newUser");

实现Observable接口的任何内容都将支持任意数量的侦听器,因此您可以随意倾听事件。

答案 1 :(得分:1)

您是否希望在致电setUser时收到回电?因为这不是它的工作方式。 setUser在绑定视图上显式设置数据模型视图。如果更改此点之外的任何数据模型属性的值,则将调用属性更改回调。将您的代码更改为此,我猜您会收到回调 -

User user = new User("sa");
binding.setUser(user);
user.setName("Johny Depp");   //you should receive the callback beyond this and the UI would update too

修改 实现Observable接口的类将允许绑定将单个侦听器附加到绑定对象,以侦听该对象上所有属性的更改。

Observable接口有一个添加和删除侦听器的机制,但通知取决于开发人员。为了简化开发,创建了一个基类BaseObservable来实现监听器注册机制。数据类实现者仍负责通知属性何时更改。这是通过将一个Bindable注释分配给getter并在setter中通知来完成的。