安卓数据绑定(类似于WPF)?

34

在发布前,我搜索了一些类似的问题 - 然而当涉及到Android和数据绑定时,我有一个普遍性的问题(我检查的其他答案没有让我进一步了解...)。假设你有一个名为Vehicle的类:

public class Vehicle {

private Owner owner;
private String brand;

//getter and setter for above attributes...

}

这里是Owner类的代码...

public class Owner {

private String name;

}

现在-我最近在研究微软WPF所采用的MVVM(ModelView-ViewModel)模式。这让我想到:假设我想绑定我的所有者对象的名称属性,该对象是Vehicle对象的子对象-在Android中是否有一些标准方法可以实现这一点?同时,我可能需要在更新Model之前验证输入。

我想象以下组件(假设MVVM):

  • 视图(活动)不包含应用程序逻辑-因此它更多或更少是空的
  • ViewModel将处理Vehicle对象的实例并对其执行操作
  • 模型本身看起来像我之前发布的代码-完全不知道View和ViewModel

现在,当我将我的EditText、TextView等添加到视图中时,我希望它们绑定到上下文对象(在这种情况下为Vehicle)的某些属性...如果我的问题不清楚或您需要进一步的信息,请告诉我:)先谢谢了。

P.s. 我认为熟悉WPF的人可能会知道我的意思?我自己刚刚读了关于WPF的文章,发现这是一种很好的处理方式。

P.P.s 我知道android binding项目,但我想知道Android中是否有一种内置方法或者是否有人遵循某种惯例:)我想这真的是一个绑定理论问题...

8个回答

25

本地数据绑定

Google推出了其本地数据绑定库!

https://developer.android.com/tools/data-binding/guide.html

这使您可以将视图编写为此类

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@{user.firstName}"/>

但是当前版本(rc1)的事件绑定机制不能绑定到继承自Observable类的方法(编译时会抛出异常;这是一个已知的bug,将被解决)。
当然,缺少双向绑定(预计在第一版中不会出现)是一个很大的缺点。
无论如何,这里有一个很好的示例项目可供使用https://github.com/saleeh93/data-binding-samples

有人成功地使用原生数据绑定库实现了双向绑定吗? - kosiara - Bartosz Kosarzycki
1
@kosiara 目前还不支持双向数据绑定,可能会在下一个版本中加入。您可以在此处关注状态:https://code.google.com/p/android-developer-preview/issues/detail?id=2095&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars。 - Ye Lin Aung
1
@kosiara 这不是直接可能的,但这个人展示了一种可能的方法:https://medium.com/@fabioCollini/android-data-binding-f9f9d3afc761 - Konrad Morawski
本地数据绑定是一个很大的进步,但只使用单向绑定就像制造一辆只能加速而不能刹车的汽车。你总是需要使用那些乏味的findViewById()方法。 - Apperside
1
嗨,我使用了@KonradMorawski的链接来理解数据绑定,并创建了一些Github示例,展示了各种基本的数据绑定示例。您可以在此处检查它们http://stackoverflow.com/a/33078797/1979347 - Rohan Kandwal

15

Android SDK中没有提供类似于MS WPF中数据绑定功能的内置功能。Google为运行Android的各种设备提供了较低级别的接口。到目前为止,Android开发社区中还没有出现更高级别的应用程序框架。(依我之见,要创建这样一个框架需要像谷歌这样的大型公司,考虑到所有不同的 Android 设备上的限制条件。)

您可以在自己的应用程序中创建一组数据绑定类,以处理MVVM模式的需求。 "Databinders"会在Android视图对象上设置相关的事件处理程序,并响应地在ViewModel对象上运行一些适当的方法。它们还会将ViewModel上的更改事件(由您定义)转换为View对象上适当的属性赋值。

对于您的应用程序来说,是否值得使用这种方式是一个判断性的问题。我的猜测是编写Databinder类需要比直接连接较低级别的View事件处理程序更多的工作量。框架主要在您不必自己编写它们时才有用。


1
我认为“怪兽公司”的评估是正确的。在WPF中,数据绑定需要大量复杂的代码,这一点令人惊讶。 - sourcenouveau
谢谢你的回复 - 是的,我也想到了 :( 在发布问题后不久,我开始有一个关于如何解决它的想法 - 它类似于你所建议的,我会看看它能带我走多远 :) 非常感谢。 - Ready4Android
32
从WPF/Silverlight/WP7过来,在Android上工作感觉像回到了GUI的石器时代 - 即使MonoDroid大大缓解了痛苦 :) - Oliver Weichhold
2
框架主要在你不必亲自编写时非常有用。这难道不正是人们首先编写框架的原因吗? - VH-NZZ
Google本身已经在创建一个数据绑定库,详见下面我的回答。 - Minelli
1
我坚持了4.5年的正确,现在却错了。唉,这就是软件堆栈崩溃的样子。 - randomfactor

14

我的Android-Binding项目旨在通过XML布局实现数据绑定。由于谷歌没有提供内置方法(我也预见不到谷歌会这样做),这就是我启动该项目的原因。


1
我看了一下你的项目,但是我认为对于我来说,更简单的东西可能就足够了。我注意到一个问题是缺乏注释,这让我很难理解所有的东西 xD ... - Ready4Android
到目前为止,我是该项目中唯一的开发人员,因此内联注释不是我要做的首要任务。你尝试过教程/示例代码吗? - xandy
@xandy 我无法运行你的任何应用程序。我只看到存储库中的一堆分支,其中没有一个附加了适当的库项目。例如,当我尝试运行dome/trunk/ABGallery时,它会要求gueei.binding.v30.BinderV30。我从https://code.google.com/p/android-binding/downloads/detail?name=android-binding-v30-0.52.jar&can=2&q=下载了它,但仍然缺少像EventAggregator这样的类:( - Shailendra Singh Rajawat
我们在生产项目中使用AB框架,它大大简化了与UI相关的代码。 - Alex Che
看来谷歌终于认为这是个好主意了 :) https://developer.android.com/tools/data-binding/guide.html - Jason Sperske
显示剩余3条评论

11

Android M将提供强大的数据绑定库!

它现在可以在开发者预览版中获得。

xmljava文件中看起来非常出色:

<TextView android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@{user.firstName}"
    />

Java Bean:

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;
   }
}

绑定:

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
   User user = new User("Test", "User");
   binding.setUser(user);
}

4
澄清一下,尽管它是M预览版,但实际上它是支持库的一部分,因此您可以在API 7之前使用它。 - yigit
谷歌在其开发者指南网站上发布了数据绑定指南:https://developer.android.com/tools/data-binding/guide.html - kosiara - Bartosz Kosarzycki
1
一个重要的警告是,它只是单向数据绑定,所以它相当无用。他们不会在v1中实现双向绑定:https://code.google.com/p/android-developer-preview/issues/detail?id=2095&sort=-stars&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars - Richard
@Richard 虽然这种限制肯定很痛苦,但基于此称其为“无用”是夸张的。在每个典型的应用程序中,都有一些只读/可重新加载的屏幕(例如从API获取的各种数据)。 - Konrad Morawski

8

阅读了关于这个主题的一些内容,我刚刚发现了RoboBinding,这是一个面向Android的“数据绑定展示模型框架”。

与Android绑定项目类似,您可以使用额外的命名空间将属性(单向或双向)和事件绑定到XML中的视图。

虽然这也不是内置的方法,但它可能会对您有很大帮助。


目前,即使有新的Google数据绑定库在视野中,我仍然选择使用它作为Android中MVVM的框架。 - Minelli

7
自你第一次提问以来,情况已经发生了很大改变。
最重要的是Stuart Lodge给了我们MVVMCross

该项目提供了一个跨平台的mvvm移动开发框架,建立在Silverlight for WP7、Mono for Android 和 MonoTouch for iOS 以及WinRT XAML framework for Windows 8 Store 应用程序之上。该项目广泛使用可移植类库,提供可维护的跨平台C#本机应用程序。

它为您的Views提供数据绑定,对ViewModels进行操作。
例如,它支持以下功能:
<EditText
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    local:MvxBind="{'Text':{'Path':'Query','Mode':'TwoWay'}}" />

资源:

Github页面: https://github.com/slodge/MvvmCross

Presentation: http://slodge.blogspot.co.uk/2012/12/mvvmcross-video-presentation-xaminar.html

还有一个非常好的入门教程:使用MVVM和数据绑定构建Android应用程序


5

除了Oleksii的回答之外,对于那些想要查看示例项目的人(似乎Google还没有提供任何示例项目),我刚刚制作了一个并将其推送到GitHub上。

几个注意点:

  • classpath "com.android.databinding:dataBinder:1.0-rc0" 对我不起作用,所以我使用 classpath group: 'com.android.databinding', name: 'dataBinder', version: '1.0-rc0'
  • 需要Java 7+
  • 如果出现错误,请尝试清理/重建。
  • 不要忘记实现android.databinding.Observableextends BaseObservable,如果您需要在数据更改时通知的能力。
  • minSdkVersion为7。这是一个支持库。
  • 我的项目不遵循MVVM,它只使用数据绑定。添加了MVVM示例。

1
我知道这篇文章有些年头了,但面对同样的问题,我找到了以下内容,希望能够减轻负担。
RoboBinding - 处理绑定 - 如上所述 RoboGuice - 进行依赖注入
有一个非常好的 RoboBinding 视频演示,可以帮助解释什么是以及如何使用。
我与这两个项目都没有关联,但它们看起来很有前途,特别是在涉及代码方面需要解决绑定问题的人。RoboBinding 还处理双向更新。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接