MVVM之BindingCommand

775 阅读1分钟

背景:

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();

}