【问题标题】:android - using dataBinding, on Activity instead of layoutandroid - 在Activity而不是布局上使用dataBinding
【发布时间】:2017-08-21 15:07:08
【问题描述】:

我正在使用 MVVM 设计模式。 我想使用 dataBinding 或 RXJava 以便在模型更改时通知视图。 dataBinding 可以在 xml 中完成。 但我想通知 Activity 模型发生变化并做一些更复杂的事情。 假设我希望我的 TextView 在文本不为空时更改颜色。 你能帮我通过 dataBinding 或 RXJava 来做吗?

这是我的代码:

xml

<?xml version="1.0" encoding="utf-8"?>

<data>

    <variable
        name="viewModel"
        type="edi.com.mydatabindingsimple.MyViewModel" />
</data>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <EditText
        android:id="@+id/editText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPersonName"
        android:text="@={viewModel.txt}" />

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

</LinearLayout>

活动

import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

import edi.com.mydatabindingsimple.databinding.ActivityMainBinding;

    public class MainActivity extends AppCompatActivity {

        MyViewModel viewModel = new MyViewModel();

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            final ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
            binding.setViewModel(viewModel);
        }
    }

视图模型

    import android.databinding.BaseObservable;
import android.databinding.Bindable;



public class MyViewModel extends BaseObservable{
    private String txt;

    @Bindable
    public String getTxt() {
        return txt;
    }

    public void setTxt(String txt) {
        this.txt = txt;
        notifyPropertyChanged(edi.com.mydatabindingsimple.BR.txt);
    }

}

【问题讨论】:

  • 但我想在模型发生变化时通知 Activity 并做一些更复杂的事情。。为什么是活动? VM 获取更改并通知属性。这应该就是全部了。如果绑定不是本机支持的,你可以使用@BindingAdapter添加你自己的
  • 感谢黑带的回答。我阅读了@BindingAdapter 并意识到它只能在setter 中使用。但我需要它在吸气剂中。如果我想在我的模型中有一些布尔标志告诉我显示/隐藏视图
  • 所以在&lt;TextView&gt; 中添加android:background="@{viewModel.textViewColor}" 并在MyViewModel 中添加@Bindable int getTextViewColor() 方法
  • @pspink,谢谢你的回答,但我不想直接在 xml 中做。当然它适用于这种特定情况,但如果我希望我的 viewModel 在不知道 View.Visible 的常数数量的情况下告诉 View 可见,我希望 Activity 能够处理它。
  • 那么您想通过活动在 xml/presenter/view-model 中设置一些视图属性(如android:text)和一些(如android:background)?是否有意义?但当然你仍然可以在MainActivity#onCreate 中调用viewModel.addOnPropertyChangedCallback(...),所以现在,当你的文本更改时,回调会在你的活动中被调用,但是......在添加回调后,你的视图模型会引用活动。这是你想避免的事情......

标签: android mvvm rx-android android-databinding rx-java2


【解决方案1】:

你可以做的是创建一个回调机制来触发你的Activity中的一个方法。这仍然会先通知 ViewModel,但效果是一样的。

您可以创建一个新界面(或将其添加到 ViewModel 中)

public interface ViewModelCallback{
   void ActionCallback();
}

在您的活动中:

public class MainActivity extends AppCompatActivity implements ViewModelCallback

在您的视图模型中

private ArrayList<ViewModelCallback> callbacks = new ArrayList<>();

public void notifyCallbacks(){
  for(ViewModelCallback c : callbacks){
     if(c != null){
         c.ActionCallback
      }
   }
}

public void addCallback(ViewModelCallback c){
     callbacks.add(c);
}

在 NotifyPropertyChanged() 之后调用 notifyCallback。 并且不要忘记将您的活动添加为 onCreate 中的回调

viewModel.addCallback(this)

您还应该在 onDestroy 中将其删除。

【讨论】:

  • 谢谢,但我不希望我的视图模型引用活动。这违反了 MVVM 原则。
  • 我不确定,这只是一个回调,它不使用适合 Android 的代码。而且您很快就会意识到,这种技巧并不意味着您的应用程序不遵循 MVVM 原则(就像 WPF 中的代码隐藏一样。代码隐藏并不意味着违反 MVVM)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-31
  • 1970-01-01
相关资源
最近更新 更多