android - MVVM databinding when model is updated by service -
solved! see below final solution
problem: trying use databinding , mvvm android app problem lies in fact model updated service separate mvvm part of app. if update model via viewmodel works fine, can't seem work out clean way of getting change model bubble viewmodel , view when model updated service.
the app: app connects external device via bluetooth , maintains serial connection sensor readings , settings streamed continuously device app in close real-time. commands can sent device via connection. model acts in-memory representation of device. different screens in app expose different sections of model user , may or may not allow them adjust values (settings).
code: (i can't show exact code here simplified version)
model:
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); } }
viewmodel:
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; } }
fragment:
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; } }
layout:
<?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>
custom application code:
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; } }
solution in end followed @exkoria 's advice , used eventbus create , send custom event:
public class devicemodelupdateevent { public final string fieldname; public final string newvalue; public devicemodelupdateevent(string field, string value){ fieldname = field; newvalue = value; } }
the put handler in viewmodel trigger databinding update in view:
@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); } }
can't add listener model viewmodel can listen changes in model , update view when changes occur? or perhaps it's nice usage event bus such one: https://github.com/greenrobot/eventbus.
Comments
Post a Comment