I have Spinner
and some count of EditText
at layout. I want to bind type of EditText
to state of Spinner
. I.e.
- for FLOAT state of
Spinner
input type of allEditText
components must be changed to floating point numbers - for INTEGER input type must be integer
To achive this I define binding adapter below:
@BindingAdapter(value = {"bind:selectedValueAttrChanged", "bind:relatedInputs"}, requireAll = false)
public static void setMeasurementUnit(final Spinner spinner, final InverseBindingListener listener, final AppCompatEditText... relatedInputs){
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
listener.onChange();
String selectedUnit = (String) spinner.getSelectedItem();
for (EditText editText : relatedInputs) {
if (editText == null) continue;
if (selectedUnit.equals("INTEGER"))
editText.setInputType(InputType.TYPE_CLASS_NUMBER);
else if(selectedUnit.equals("FLOAT"))
editText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
}
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
listener.onChange();
}
});
}
And bind EditText
to Spinner
at layout file:
<LinearLayout>
<android.support.v7.widget.AppCompatEditText
android:id="@+id/edit_text_1"/>
<android.support.v7.widget.AppCompatSpinner
bind:relatedInputs="@{editText1}"/>
</LinearLayout>
It's produce the error at compile time:
data binding error ****msg:Cannot find the setter for attribute 'bind:relatedInputs' with parameter type android.support.v7.widget.AppCompatEditText on android.support.v7.widget.AppCompatSpinner.
When I tried declare and pass array of EditText
<android.support.v7.widget.AppCompatSpinner
bind:relatedInputs="@{new AppCompatEditText[]{editText1, editText2}}"/>
I'm got syntax error:
data binding error ****msg:Syntax error: extraneous input 'AppCompatEditText' expecting {<EOF>, ',', '.', '::', '[', '+', '-', '*', '/', '%', '<<', '>>>', '>>', '<=', '>=', '>', '<', 'instanceof', '==', '!=', '&', '^', '|', '&&', '||', '?', '??'}
How I can pass variable number of arguments to databinding adapter?
or
How to declare array for databinding at layout file?
P.S. this example very simplified and can contain logical errors, but it fully explain, what I want to achive.
Another approach would be:
Add a listener to your spinner:
And in your xml, for every
EditText
you want:A decimal input corresponds to
InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL
, an integer input corresponds toInputType.TYPE_CLASS_NUMBER
.It is possible to enter a float and change the selection to int - you'll need to add an error or something to prevent this.
Android Data Binding doesn't let you pass in varargs. You may have only have one value for each attribute. You may pass lists or arrays as attribute values, but you can't create them on the fly (
new
is not allowed in the expression language).It is better to invert the problem and assign the
android:inputType
attribute to an expression based on the selected item.You'll need the Converters class also: