如何将可变数量的参数传递给数据绑定适配器?
How to pass variable number of arguments to databinding adapter?
我有 Spinner
和一些 EditText
的布局。我想将 EditText
的类型绑定到 Spinner
的状态。 IE。
- 所有
EditText
组件的FLOAT状态Spinner
输入类型必须更改为浮点数
- for INTEGER 输入类型必须是整数
为了实现这一点,我在下面定义了绑定适配器:
@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
}
}
我有 Spinner
和一些 EditText
的布局。我想将 EditText
的类型绑定到 Spinner
的状态。 IE。
- 所有
EditText
组件的FLOAT状态Spinner
输入类型必须更改为浮点数 - for INTEGER 输入类型必须是整数
为了实现这一点,我在下面定义了绑定适配器:
@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
}
}