如何将可变数量的参数传递给数据绑定适配器?

How to pass variable number of arguments to databinding adapter?

我有 Spinner 和一些 EditText 的布局。我想将 EditText 的类型绑定到 Spinner 的状态。 IE。

为了实现这一点,我在下面定义了绑定适配器:

@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();
        }
    });
}

并在布局文件中将 EditText 绑定到 Spinner

<LinearLayout>
    <android.support.v7.widget.AppCompatEditText
         android:id="@+id/edit_text_1"/>

    <android.support.v7.widget.AppCompatSpinner
         bind:relatedInputs="@{editText1}"/>
</LinearLayout>

编译时报错:

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.

当我尝试声明并传递 EditText

的数组时
<android.support.v7.widget.AppCompatSpinner
         bind:relatedInputs="@{new AppCompatEditText[]{editText1, editText2}}"/>

我遇到语法错误:

data binding error ****msg:Syntax error: extraneous input 'AppCompatEditText' expecting {<EOF>, ',', '.', '::', '[', '+', '-', '*', '/', '%', '<<', '>>>', '>>', '<=', '>=', '>', '<', 'instanceof', '==', '!=', '&', '^', '|', '&&', '||', '?', '??'}

如何将可变数量的参数传递给数据绑定适配器?

如何在布局文件中为数据绑定声明数组?

P.S。这个例子非常简单,可能包含逻辑错误,但它充分说明了我想要实现的目标。

另一种方法是:

//create a Observable for the input type:
public final ObservableInt decOrInt = new ObservableInt(InputType.TYPE_NUMBER_FLAG_DECIMAL);

向微调器添加一个侦听器:

binding.spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
            decOrInt.set(i != 0 ? 
                    InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL : 
                        InputType.TYPE_CLASS_NUMBER);
        }

        @Override
        public void onNothingSelected(AdapterView<?> adapterView) {
            decOrInt.set(InputType.TYPE_CLASS_NUMBER);
        }
    });

在你的 xml 中,你想要的每个 EditText

<!-- act would be the class where you store your decOrInt-->
<EditText
        android:id="@+id/edit_text"
        android:inputType="@{act.decOrInt}" /> 

小数输入对应InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL,整数输入对应InputType.TYPE_CLASS_NUMBER.

可以输入一个浮点数并将选择更改为整数 - 您需要添加一个错误或其他内容来防止这种情况发生。

Android 数据绑定不允许您传入可变参数。每个属性可能只有一个值。您可以将列表或数组作为属性值传递,但不能即时创建它们(new 在表达式语言中是不允许的)。

最好反转问题,根据所选项目将 android:inputType 属性分配给表达式。

<LinearLayout>
    <android.support.v7.widget.AppCompatEditText
         android:inputType="@{Converters.getInputType(spinner1.selectedItem)}"/>

    <android.support.v7.widget.AppCompatSpinner
         android:id="@+id/spinner1"/>
</LinearLayout>

您还需要转换器 class:

public class Converters {
    public static int getInputType(Object obj) {
        if (!(obj instanceof String)) {
            return InputType.TYPE_CLASS_TEXT; // Don't know what to do
        }

        String selectedUnit = (String) obj;

        if (selectedUnit.equals("INTEGER")) {
            return InputType.TYPE_CLASS_NUMBER;
        } else if(selectedUnit.equals("FLOAT")) {
            return InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL;
        }
        return InputType.TYPE_CLASS_TEXT; // Don't know what to do
    }
}