Android: Android Binding - Introduction
Android Binding - Introduction
Introduction
Android Binding is a new Open Source Framework for Android-Java providing XML layout view binding mechanism. It helps development of Android Application by decoupling the View widgets and backend Activities. It works best with MVP or MVVM patterns.
Please also download fromMarket(Search "Markup Demo") the demo on most features of Android Binding.
A more fundamental, getting started toAndroid MVVM with android-binding tutorial seriesis up in my own blog.
UPDATE: v0.2 is released. Please visit the project homepage for details as it may not be compatible with previous versions.
Critical Changes (as of 30/1/2010)
If this is the first time you read this article, you may skip this section.
Version 0.11 of Android binding is released with this sample application. As the project evolves, a number of critical (yet would results breaking original codes) changes were made. Upon the release of 0.11, I suppose those changes should be final.
Thefirst time I wrote this article, Android Binding doesn't support binding to object collections, but now, it can bind to Cursor or Array, each 'row' of the records are treated as a View Model, which meansCommand
andDependentObservables
are
all functional, which would be covered later in this article.
The sample application is rewritten, as the Contacts list no longer binds to the raw Adapter but via a more declarative way. Action related binding renamed to have a 'on-' prefix, for example, click -> onClick to make it more distinctive.
Observable<T>
now requires passing the class ofT
as
parameter: e.g.
Observable<Boolean>(Boolean.class, true);
Since this makes writing such code too verbose, some shorthand primitive observables are provided.
Sample Application
The following will briefly introduce how it is used. Where the sample application codes used here are obtainable at:
and the compiled application is available at Android Market (Search "Android Binding" in Market).
This sample isa modification based on Google's originalContact Manager Sample, the purpose of it is to show the differences in view binding and the benefits of using Android Binding.
Basic Configuration
To use Android Binding, all you need to do is to reference the library (in Eclipse, right click project -> Properties -> Android, reference the Android Binding Project as library). And then, inApplication
class:
public class ContactManagerApplication extends Application { @Override public void onCreate() { super.onCreate(); Binder.init(this); } }
TheBinder.init(Application)
is required to run once and only once, across the application life cycle. During theinit()
process,
it is time for Android Binding to register and initialize the markup and binding providers, which can support custom view classes.
Activity
Activity is no longer required to be View-awared, even the view model doesn't. Android Binding is best supported for View Model First development in MVVM. So, no more presentation / user interaction logic inActivity
and
results in a cleanActivity
class:
public final class ContactManager extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ContactManagerModel model = new ContactManagerModel(this); Binder.setAndBindContentView(this, R.layout.contact_manager, model); } }
You provide theModel
(orViewModel
to
be precise) to binder, and it automatically wires up theview
with theViewModel
.
This is how we markup thecontact_manager.xml:
Layout
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:binding="http://www.gueei.com/android-binding/" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ListView android:layout_width="fill_parent" android:layout_height="wrap_content" binding:itemSource="ContactList" binding:itemTemplate="@layout/contact_entry" android:layout_weight="1"/> <CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" binding:checked="ShowInvisible" binding:onCheckedChange="PopulateList" android:text="@string/showInvisible"/> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" binding:onClick="AddContact" android:text="@string/addContactButtonLabel"/> </LinearLayout>
Layout looks pretty much the same as standard Android Layout, except that an extrabinding
namespace is imported.There's
an issue with AAPT, that the binding namespace needed to reference to the "demo" project instead of the library. (Hope it can be solved in the coming future).The binding namespace should point tohttp://www.gueei.com/android-binding/.
As shown in the above layout file, the markup is done through the custom namespace (prefixed binding), and the attribute is pretty much reflecting to most originalView
attributes.
There are currently two kinds of bindable objects in a view. First is theProperty
(likechecked
inCheckBox
)
and the second isCommand
(checkedChange
inCheckbox
),
where both of them will be explained in thelater part of this article.
Also note that for theListView
, it is binding toitemSource
which
will be either someCursor
orArray
of View
Models (and we will cover that later) and theitemTemplate
is a standard Android Resource reference format, that tells what the layout ofeachitem
should look like.
Following is thecontact_entry.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:binding="http://www.gueei.com/android-binding/" android:layout_width="wrap_content" android:layout_height="wrap_content" binding:onClick="ShowContact" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="20dip" binding:text="Name" /> </LinearLayout>
It is still fairly standard layout XML file with customized binding namespace. Notice that the layout root (i.e. theLinearLayout
)
defined an actiononClick
.
ViewModel
TheViewModel
is something that bridges theView
andModel
(it
will be the contact provider in this example). TheViewModel
in Android Binding is a class defining all the 'bindable' data/command Fields for theView
to
access. Following shows a portion of theViewModel
:
public class ContactManagerModel { private Activity mContext; public CursorSource<ContactRowModel> ContactList = new CursorSource<ContactRowModel> (ContactRowModel.class, new Factory()); public BooleanObservable ShowInvisible = new BooleanObservable(false); public Command PopulateList = new Command(){ public void Invoke(View view, Object... args) { populateContactList(); } }; public Command AddContact = new Command(){ public void Invoke(View view, Object... args) { launchContactAdder(); } }; private void populateContactList() { // Build adapter with contact entries Cursor cursor = getContacts(); ContactList.setCursor(cursor); }
BooleanObservable
is representing an object that is 'observable' by other objects, so, whatever changes are made on this object
will keep its observers notified. There are quite someObservables
defined in Android Binding, likeStringObservable
,IntegerObservable
,
... all of them are subclasses ofIObservable<T>
which implement thefollowing methods:
set()
get()
notifyChanged()
Theget()
andset()
are
a replacement for getter and setter methods in Java, which will, by default, notify the subscribers about the change on the object automatically (where this is a borrowed concept from .NET).
Command
is the interface that defines something that is "Executable". Normally they will be wired withEvent
fired
from User Interface.
Finally, since our contact source is a cursor, we need to supply theCursorSource<?>
to indicate how ourCursor
is
used.
Binding to Cursor
In Android Binding, each row of record in theCursor
, is supposed to be a View Model. That means, you are applying the same layout
each with a separate set of data. One of the most powerful features in Android Binding, is that it allows you to define Commands and more complicated logic even in the sub-view models. As mentioned before, you cannot just supply aCursor
asitemSource
forAdapterViews
(includingListView
,Spinners
...),
but it must be either anArraySource
orCursorSource
.
CursorSource
takes two constructor parameters:
public CursorSource<ContactRowModel> ContactList = new CursorSource<ContactRowModel> (ContactRowModel.class, new Factory());
First one is the class of the sub-viewmodel that representing each 'row' of cursor data (so it is namedrowModel
), the other
one is a factory that actually knows how to 'construct' the row. Let's look at them one by one.
public class ContactRowModel extends CursorRowModel { public IdField Id = new IdField(0); public StringField Name = new StringField(1); public Command ShowContact = new Command(){ //...
TheRowModel
is pretty much standard View Model, except it requires to extend fromCursorRowModel
.
TheIdField
,StringField
are simplyObservables
but
their value will be filled up automatically using theCursor
; the number within the bracket tells which column you are mapping that field to.
Model Validation
Model validation (to be precise, validating the View Model) is also supported, this is also demonstrated in this sample application but you may read my otherarticlefor details.
Furthermore
Observable
is quite restricted at the moment, as it requires the View Attribute and the Property of Model to be the same in type.
That means, if you bind thechecked
(which is boolean) attribute with anObservable<Integer>
,
it won't work, since implicit type casting is not allowed. Therefore, another two subclasses ofObservable
are provided:
DependentObservable<?>
This denotes that anobservables
' value is dependent on otherObservables
.
For example, we can rewrite the aboveViewModel
to add anSelectedContact:
DependentObservable<Contact> SelectedContact = new DependentObservable<Contact>(Contact.class, SelectedId){ @Override public Contact calculateValue(Object... args){ getContactFromDb((Integer)args[0]); } };
DependentObservable
requires only one override method, thecalculateValue
.
SinceDependentObservable
can depends on multiple dependents, the parameters length incalculateValue
is
open, and explicit typecast is required. The above example is similar to a one-way converter, that converts theId
to a real contact.
There's actually aConverter
class in Android Binding, and the only difference withDependentObservable
is
thatConverter
can allow two-way binding:
Converter<?>
public abstract void ConvertBack(T value, Object[] outResult);
Indeed,Converter
is a subclass ofDependentObservable
.
It depends on a list of otherobservables
, it can convert a booleantrue
to
number1
, and when the convert back when other changes the convert's value.
Progress and Plans
An Alpha version of the project is released. You can go to the project homepage to download it.
Future plan is to add support to more POJO (Plain Old Java Object) way of View Model declaration.
You are free to download the code from the Google Code project repository, reports and issues. Please drop in the discussion group:http://groups.google.com/group/androidbinding.
Conclusion
This article briefly introduces the functionality of the Android Binding. If you compare it to the original Contact Manager Sample, you will find that using Android Binding w/MVVM results in much cleaner code and thus, more friendly to Unit testing and better code quality. Active development is in progress and this is my first OSS. I really look forward to comments and suggestions on this framework.
Author Blog and Project Details
- Andy Tsui
- Blog:http://andytsui.wordpress.com
- Discussion on project:http://groups.google.com/group/androidbinding
- Project hosting:http://code.google.com/p/android-binding/
License
This article, along with any associated source code and files, is licensed underThe GNU Lesser General Public License (LGPLv3)
About the Author
xandytsui |
相关推荐
这部分将阐述如何使用DependencyService和Binding库来调用平台特有的功能,如GPS、相机和通知。 5. **数据持久化与网络通信**:在移动应用中,数据管理至关重要。书中会讨论SQLite数据库的使用,以及如何通过HTTP...
android-data-binding-rxjava Simple demo developed with love at Tango which demonstrates how to wrap Android DataBinding ObservableField into RxJava's Observable. With this solution it is possible to...
《深入解析YCSB-HBase14-Binding 0.17.0》 YCSB(Yahoo! Cloud Serving Benchmark)是一种广泛使用的云数据库基准测试工具,它为各种分布式存储系统提供了标准化的性能评估框架。YCSB-HBase14-Binding 0.17.0是针对...
Data Binding Validator by Ilhasoft ... compile 'com.github.Ilhasoft:data-binding-validator:LATEST-VERSION' } Latest Version: Features: Minimum/Maximum length validation for text fi
资源来自pypi官网。 资源全名:channels_binding-1.4.21-py3-none-any.whl
资源分类:Python库 所属语言:Python 资源全名:channels_binding-1.1.5-py3-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
1. 集成开发环境:Android Studio提供了一个全方位的开发环境,包括代码编辑器、调试器、构建工具等,使得开发者可以高效地编写、测试和调试代码。 2. Gradle支持:Android Studio使用Gradle作为默认的构建系统,...
ucrop-android-binding-master 是一个与Android相关的开源项目,主要涉及图像裁剪库的绑定。这个压缩包中的内容可能包括源代码、构建文件和其他资源,旨在帮助开发者在自己的Android应用中集成高自定义性的图片裁剪...
Android Data Binding库是Google提供的一个工具,用于简化UI与数据模型之间的交互。它允许开发者在XML布局文件中直接绑定数据,减少在Activity或Fragment中处理点击事件和更新UI的样板代码。通过Data Binding,我们...
RxJava binding APIs for Android UI widgets from the platform and support libraries. Download Platform bindings: compile 'com.jakewharton.rxbinding2:rxbinding:2.0.0' 'support-v4' library bindings: ...
《JGoodies Binding 2.6:数据绑定与UI交互的高效工具》 JGoodies Binding 是一个开源的Java库,专注于数据绑定和事件处理,它使得Java Swing应用中的模型和视图之间的交互变得更加简单、直观。这个库的版本号为2.6...
android-data-binding-example 来自 Google I/O 2015 的 Android 数据绑定示例 要求:分钟。 Android Studio 1.3 测试版 1 分钟tools.build:gradle:1.2.3 & databinding:dataBinder:1.0-rc0 分钟。 构建工具版本...
本文将重点介绍Xamarin Android库——JW Player Android SDK的绑定库,即“jwplayer-android-binding”,以及如何在Xamarin Android项目中使用它。 首先,我们来理解“Xamarin Android绑定库”的概念。Xamarin是...
binding-collection-adapter 1.2 更进一步:view -> data -> view 在本项目中,你将会看到一个带有 下拉刷新 上拉加载 的页面如何简化到10 行java代码 ! see NotifyVM.kt 2. 模块概览 > 接口全抓自掘金app, 支持...
<layout xmlns:android="http://schemas.android.com/apk/res/android"> name="user" type="com.example.myapp.User" /> android:layout_width="match_parent" android:layout_height="match_parent" ...
本项目“Android-View-Binding-Samples”提供了丰富的示例,帮助开发者深入理解并熟练掌握这一特性。下面将详细探讨Android View Binding的基本概念、优势以及如何在实际项目中应用。 1. **View Binding简介** ...
标题中的"win32-x64-64-binding.node"是一个特定于操作系统的二进制模块,用于Node.js环境。这个文件是Node.js扩展的一部分,它允许开发者利用C++或者其他低级语言编写的库,为JavaScript提供更强大的功能。这里的...