Something must be missing for me. Every example I saw with a two-way binding for Android is based on String in the backup data for any user input, like EditText .
Processing something, rather than a string, seems somewhat ... inelegant. For example, if I have a double in my domain model that needs to be editable, the best binding I came up with requires a ViewModel with a surprisingly large amount of code for the interaction between the model and EditText .
Did I miss something? Should I really need 30 lines of code for the EditText interface with a double? For discussion, consider a currency field, represented as a double, in a two-way EditText border:
<EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:inputType="numberDecimal" android:text="@={fragModel.startBucks}" android:id="@+id/editText2"/>
And here is the ViewModel that I had to build to give the EditText a string to bind to.
@Bindable private String startBucksString; private double localBucks; public String getStartBucksString() { double domainBucks = cd.getStartBucks(); // Ignore incoming change of less than rounding error if( Math.abs(localBucks - domainBucks) < .001 ) return startBucksString; startBucksString = ""; if( domainBucks != 0) startBucksString = String.format("$%.2f", domainBucks); return startBucksString; } public void setStartBucksString(String inBuckstr) { double calcBucks=0; inBuckstr = inBuckstr.replaceAll( "[^\\d.]", "" ); try { calcBucks = Double.parseDouble(inBuckstr); } catch( NumberFormatException e) { return; } // Neglect outgoing change of less than rounding error if( Math.abs(localBucks - calcBucks) < .001 ) return; startBucksString = String.format("$%.2f", calcBucks); localBucks = calcBucks; cd.setStartBucks(calcBucks); notifyPropertyChanged(BR.startBucksString); }
Here I wrote a simple, compiled example of two-way binding with ViewModel . This illustrates the difficulty that I experienced with constantly updating the float in the domain model - in the end, I decided that there was no way to do this without writing a special TextWatcher for each domain.
source share