背景:
MVVM中,按照规范view层是需要尽可能少的写逻辑,但是当有点击事件,下拉刷新等需要更新数据的情况时,我们又不得不在view中去调viewmodel层的相关逻辑
思考:
有没有办法绕过view层, 将viewmodel和这样的逻辑直接绑定起来呢?
既然viewmodel已经通过databinding 和xml布局绑定了,我们能通过databinding来实现呢?
实例:
下面来看看利用databinding 和 BindingCommand来实现按钮的点击事件: 当点击按钮的时候去网络请求数据(例子中一Toast代替)
- 1.首先在viewmodel中定义clickCommand
public BindingCommand clickCommand = new BindingCommand(new BindingAction() {
@Override
public void call() {
ToastUtil.show("clickCommand 执行 数据处理");
}
});
- 2.layout.xml中绑定viewmodel
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type="com.feng.myview.mvvm.viewmodel.MainViewModel" />
</data>
<LinearLayout
android:id="@+id/rootView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorAccent"
android:orientation="vertical">
<Button
android:text="testCommand"
bind:clickCommand="@{viewModel.clickCommand}"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</layout>
MainActivity.java
dataBinding.setViewModel(viewModel);
- 3.BindingAdapter 将按钮的点击事件与viewmodel中的clickCommand关联,当点击按钮时,触发viewmodel中命令的执行
@BindingAdapter(value = "clickCommand")
public static void click(Button button, BindingCommand clickCommand) {
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
clickCommand.execute();
}
});
}
BindingCommand.java
public class BindingCommand<T> {
private BindingAction execute;
public BindingCommand(BindingAction execute) {
this.execute = execute;
}
public void execute() {
if (execute != null) {
execute.call();
}
}
}
BindingAction.java
public interface BindingAction {
void call();
}