【问题标题】:MVVM databinding when model is updated by service服务更新模型时的 MVVM 数据绑定
【发布时间】:2017-03-24 17:46:58
【问题描述】:

已解决!最终解决方案见下文

问题: 我正在尝试将数据绑定和 MVVM 用于 android 应用程序,但问题在于模型是由与应用程序的 MVVM 部分分开的服务更新的。 如果我通过视图模型更新模型,它可以正常工作,但我似乎无法找到一种干净的方法来更改模型以冒泡到视图模型,然后在服务更新模型时冒泡到视图.

应用程序: 该应用程序通过蓝牙连接到外部设备,然后保持串行连接,其中传感器读数和设置从设备连续流式传输到应用程序,接近实时。命令也可以通过此连接发送到设备。 该模型充当设备的内存表示。应用中的不同屏幕向用户展示模型的不同部分,并且可能允许也可能不允许他们调整某些值(设置)。

代码:(我无法显示我的确切代码,但这里是简化版)

型号:

public class DeviceModel extends BaseObservable {

private int mode;

@Bindable
public int getMode(){
    return mode;
}

public void setMode(int mode) {
    this.mode = mode;
    notifyPropertyChanged(BR.mode);
}
}

视图模型:

public class BasicViewViewModel extends BaseObservable {
private final Context mContext;
private ObservableField<DeviceModel> modelFields;

public BasicViewViewModel(Context context){
    mContext = context.getApplicationContext();
    ApplicationBase app = ApplicationBase.getInstance();
    modelFields = new ObservableField<>(app.dModel);
}

    @Bindable
public String getMode(){
    return modelFields.get().Mode;
}
}

片段:

public class BasicViewFragment extends Fragment {
private FragmentBasicViewBinding mBinding;
private BasicViewViewModel mViewModel;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState){
    mViewModel = new BasicViewViewModel(getContext());
    mBinding = DataBindingUtil.inflate(
            inflater, R.layout.fragment_basic_view, container, false);
    View view = mBinding.getRoot();
    mBinding.setDevice(mViewModel);
    return view;
}
}

布局:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
    <variable name="device" type="com.example.android.bluetoothcomms.BasicViewViewModel"/>
</data>
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<TextView
    android:text="@{device.mode}"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/tvModeVal" />

</RelativeLayout>
</layout>

自定义应用代码:

public class ApplicationBase extends Application {

private static ApplicationBase instance;
public BluetoothCommsService btComms;
public DeviceModel dModel;


@Override
public void onCreate(){
    super.onCreate();
    instance = this;
    dModel = new DeviceModel();
    btComms = new BluetoothCommsService();

}

public static ApplicationBase getInstance(){
    return instance;
}
}

解决方案 最后,我遵循了@exkoria 的建议并使用 EventBus 创建和发送自定义事件:

public class DeviceModelUpdateEvent {

public final String fieldName;
public final String newValue;

public DeviceModelUpdateEvent(String field, String value){
    fieldName = field;
    newValue = value;
}
}

我在视图模型中放置了一个处理程序来触发视图中的数据绑定更新:

@Subscribe
public void onMessageEvent(DeviceModelUpdateEvent event){
    switch(event.fieldName){
        case "yieldLevel":
            notifyPropertyChanged(BR.yieldLevel);
            break;
        case "mode":
            notifyPropertyChanged(BR.mode);
            break;
        case "deviceType":
            notifyPropertyChanged(BR.deviceType);
            break;
        case "firmwareVersion":
            notifyPropertyChanged(BR.firmwareVersion);
    }
}

【问题讨论】:

    标签: android mvvm data-binding android-databinding


    【解决方案1】:

    您不能只为您的模型添加一个侦听器,以便您的视图模型可以侦听模型中的更改并在发生更改时更新视图吗?或者,对于像这样的事件总线来说,这可能是一个很好的用法:https://github.com/greenrobot/EventBus

    【讨论】:

    • 谢谢!老实说,我完全忘记了那个图书馆,而且奇怪的是它没有出现在我的任何谷歌搜索中。
    猜你喜欢
    • 1970-01-01
    • 2021-11-10
    • 1970-01-01
    • 2012-05-13
    • 2014-05-05
    • 1970-01-01
    • 2015-12-17
    • 2018-06-30
    • 1970-01-01
    相关资源
    最近更新 更多