如何将架构组件与android上的数据绑定结合起来?

Posted

技术标签:

【中文标题】如何将架构组件与android上的数据绑定结合起来?【英文标题】:how to combine Architecture Components with data binding on android? 【发布时间】:2017-10-20 00:39:54 【问题描述】:

我已经开发了基于android数据绑定库的app:https://developer.android.com/topic/libraries/data-binding/index.html

class SignInViewModel extends BaseObservable 

    @Bindable
    public String getLogin() 
        return login;
    

    @Bindable
    public String getPassword() 
        return password;
    

现在我想使用新库中的 ViewModelProviders: https://developer.android.com/topic/libraries/architecture/guide.html

SignInViewModel signInViewModel = ViewModelProviders.of(this).get(SignInViewModel.class);

它是如何结合的?任何想法?还是应该将这两个库结合起来?

编辑

我改成:

class SignInViewModel extends ViewModel 
   public ObservableField<String> login = new ObservableField<>("");

    public ObservableField<String> password = new ObservableField<>("");

现在编译,但问题是:它是正确的方式吗?

【问题讨论】:

我找到了一个关于这个话题的article。简短的回答,目前没有“正确”的方法,我们可能不得不等待数据绑定团队自己的一些消息。 【参考方案1】:

这是一个已知的不兼容问题。不能同时扩展BaseObservableAndroidViewModel,所以不能使用@Bindable进行双向数据绑定impossible*。

这将在 Arch 组件 1.0 最终版(在数据绑定方面)之后修复。

*编辑:您可以制作自己的 ObservableViewModel:https://gist.github.com/JoseAlcerreca/4b66f9953d50b483d80e6b9ad7172685

【讨论】:

作为一种解决方法,使用 ObservableField 的解决方案是正确的方法吗? 是的,如果您可以限制使用ObservableFields,那就没问题了。 @JoseAlcérreca 现在架构组件在 1.0 中,在将它们与 DataBinding 结合时我看不到任何差异,还是我遗漏了什么?我至少在发行说明中找不到任何关于此的内容。 在数据绑定方面已经完成,并且正在工作中! 您好.. 有人可以提供一个示例链接,该链接使用 ViewModel 和上面讨论的 2 路数据绑定。拜托……【参考方案2】:

可能在提出问题时不存在,但本文中解释了另一个选项:https://medium.com/google-developers/android-data-binding-observability-9de4ff3fe038

基本上,您可以实现 android.databinding.Observable,而不是从 BaseObservable 扩展。

因为您还需要执行以下操作,所以需要做更多的工作:

    在你的模型类中创建这个变量

    private PropertyChangeRegistry registry = new PropertyChangeRegistry();
    

    像这样实现被覆盖的方法

    @Override
    public void addOnPropertyChangedCallback(OnPropertyChangedCallback callback) 
        registry.add(callback);
    
    
    @Override
    public void removeOnPropertyChangedCallback(OnPropertyChangedCallback callback) 
        registry.remove(callback);
    
    

    用这些替换所有“BR”调用:

    registry.notifyChange(this, BR.bar);
    

其他一切都与从 BaseObservable 扩展相同。所以我认为这可能是 Jose 可能暗示的解决方案,当时可能不可用。它似乎有效。

更新: 正如 Eugene Brusov 所提到的,您现在可以将 LiveData 与数据绑定一起使用。这就是我现在正在做的事情,使用更少的样板就容易多了。见https://developer.android.com/topic/libraries/data-binding/architecture。

【讨论】:

【参考方案3】:

Android Studio 3.1 Canary 6 (https://androidstudio.googleblog.com/2017/12/android-studio-31-canary-6-is-now.html) 可以实现:

您现在可以将 LiveData 对象用作数据绑定表达式中的可观察字段。 ViewDataBinding 类现在包含一个新的 setLifecycle 方法,您需要使用它来观察 LiveData 对象。

您可以在此Medium post 中找到更多详细信息和示例。

【讨论】:

【参考方案4】:

这也可以使用包装器解决:

class SignInViewModelWrapper extends ViewModel 
    public final SignInViewModel model = new SignInViewModel();


class SignInViewModel extends BaseObservable 

    @Bindable
    public String getLogin() 
        return login;
    

    @Bindable
    public String getPassword() 
        return password;
    

然后你可以像这样得到视图模型:

SignInViewModel signInViewModel = ViewModelProviders.of(this).get(SignInViewModelWrapper.class).model;

【讨论】:

以上是关于如何将架构组件与android上的数据绑定结合起来?的主要内容,如果未能解决你的问题,请参考以下文章

如何将来自子组件的两个值与事件结合起来?

JetpackDataBinding 架构组件 ( 数据绑定技术简介 | Android 中的 DataBinding 数据绑定 | 启动数据绑定 | 定义数据类 | 布局文件转换 )

Android jetpack架构组件LiveData实战与源码解析

来自 Transformation 的数据绑定 LiveData - Android Kotlin

将 LiveData 与数据绑定一起使用

如何将 React 钩子(useContext、useEffect)与 Apollo 反应钩子(useQuery)结合起来