DataBinding简介
DataBinding是由谷歌公司于2015年发布的Android数据绑定库,已更新为正式版。
DataBinding使我们远离了findViewById和各种的setValue,大大大简化了开发工作,也是的Android从官方层面上支持MVVM模式的体现。
问题来源
用过此框架的童鞋们知道,DataBinding库虽然已经实现了单向绑定,即数据的改变直接影响视图显示,但是没有实现双向绑定,即视图的改变影响数据。这离MVVM模式还差了一步。是否有解决的方案呢?答案是肯定的。
![MVVM示意图]()
实现Data Binding双向绑定
废话说完,步入正题,我们实现原则是,尽量少写代码,尽量用原有的框架实现。(谁叫我懒呢)实现的原理便是绑定事件监听。在Data Binding中官方集成了很多实用的事件绑定,他们的声明藏在android.databinding.adapters
包下以BindingAdapter
为结尾的类中,下图为包中的部分截图。(全部的太长了,手懒)
![BindingAdapter]()
举个栗子
接下来我们就以EditText为例实现数据的双向绑定。 对于EditText控件我们需要绑定一个事件监听内容的实时变化,好在Data Binding已经在android.databinding.adapters包下的TextViewBindingAdapter为我们定义好了监听,我们可以通过在布局文件中用android:afterTextChanged=function(Editable s)
实现,如果把它和元素的setter函数绑定,就可以不用增加单独的监听函数。 下面是实例代码
ViewModel层
1 2 3 4 5 6 7 8 9 10 11 12
| public class ViewModel extends BaseObservable { private ObservableField<String> userName; public ViewModel() { userName=new ObservableField<>(); } public String getUserName() { return userName.get(); } public void setUserName(Editable userName) { this.userName.set(String.valueOf(userName)); } }
|
View层-XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| <?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context="com.xiezt.test.MainActivity">
<data>
<variable name="viewModel" type="com.example.databinding.ViewModel"/> </data>
<LinearLayout android:id="@+id/mainLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">
<EditText android:id="@+id/edit" android:layout_width="match_parent" android:layout_height="wrap_content" android:afterTextChanged="@{viewModel.setUserName}" android:text="@{viewModel.userName}"/>
<Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onclick" android:text="OK"/> </LinearLayout> </layout>
|
View层 Activity
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class MainActivity extends AppCompatActivity { private ActivityMainBinding binding; private ViewModel viewModel;
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this, R.layout.activity_main); viewModel = new ViewModel(); binding.setViewModel(viewModel); }
public void onclick(View view) { Toast.makeText(getApplicationContext(), viewModel.getUserName(), Toast.LENGTH_LONG).show(); } }
|
效果图
![效果图]()
总结
在官方还没有进一步完善此框架时,用现有的事件绑定来实现双向绑定算作是较为简单的解决方案。其他控件的双向绑定的解决思路,由于EditText事件的特殊性,我们不用单独写函数,但是其他控件不一定,例如CheckBox,它的绑定函数需要需要传递两个值,需要我们自己单独写。
相关链接