Android数据绑定,在2个编辑文本中收听更改
我已经找到了这个问题,但它对我来说并不奏效。我有一个货币转换器和两个编辑文本,从印度卢比转换为美元,反之亦然。我需要使用数据绑定来侦听每个Edittext的更改,并更新下一个Edittext的货币值 她的密码是我的Android数据绑定,在2个编辑文本中收听更改,android,data-binding,Android,Data Binding,我已经找到了这个问题,但它对我来说并不奏效。我有一个货币转换器和两个编辑文本,从印度卢比转换为美元,反之亦然。我需要使用数据绑定来侦听每个Edittext的更改,并更新下一个Edittext的货币值 她的密码是我的 public class BindingViewModel extends BaseObservable { public ObservableField<Double> inr = new ObservableField<>(); public Observ
public class BindingViewModel extends BaseObservable {
public ObservableField<Double> inr = new ObservableField<>();
public ObservableField<Double> dollar = new ObservableField<>();
public void onINRTextChanged(CharSequence s, int start, int before, int count) {
double aDouble = Double.parseDouble(s.toString());
dollar.set(aDouble * 0.014);
}
public void onDOLLARTextChanged(CharSequence s, int start, int before, int count) {
Log.d("tag", "onTextChanged " + s);
double aDouble = Double.parseDouble(s.toString());
inr.set(71.92 * aDouble);
}
}
公共类BindingViewModel扩展了BaseObservable{
公共可观察字段inr=新可观察字段();
公共可观察字段美元=新可观察字段();
public void onINRTextChanged(字符序列、int start、int before、int count){
double-aDouble=double.parseDouble(s.toString());
美元/套(双倍*0.014);
}
公共void onDOLLARTextChanged(字符序列,int start,int before,int count){
Log.d(“标记”、“onTextChanged”+s);
double-aDouble=double.parseDouble(s.toString());
印度卢比(71.92*双倍);
}
}
和XML
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="vm"
type="android.com.tasks.BindinfViewModel" />
</data>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="@+id/inr"
android:layout_width="108dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:ems="10"
android:inputType="number"
android:onTextChanged="@{vm.onDOLLARTextChanged}"
android:text="@{String.valueOf(vm.inr)}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.17"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/dollar"
android:layout_width="108dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:ems="10"
android:inputType="number"
android:onTextChanged="@{vm.onINRTextChanged}"
android:text="@{String.valueOf(vm.dollar)}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/inr"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="INR"
app:layout_constraintEnd_toEndOf="@+id/inr"
app:layout_constraintStart_toStartOf="@+id/inr"
app:layout_constraintTop_toBottomOf="@+id/inr" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="DOLLAR"
app:layout_constraintEnd_toEndOf="@+id/dollar"
app:layout_constraintStart_toStartOf="@+id/dollar"
app:layout_constraintTop_toBottomOf="@+id/dollar" />
</android.support.constraint.ConstraintLayout>
</layout>
在这里,每当我在任何一个EditText中输入内容时,这两个文本都将进入一个无限循环,因为两个文本更改侦听器在每次值更新时都会不断触发。我可以通过手动将
TextWatcher
添加到每个editText
并在设置值之前临时将textChangelistener设置为null
来解决此问题,以避免无限循环。使用数据绑定还有其他有效的方法吗?我建议您使用双向绑定。您可以为如下字段编写setter和getter,然后使用android:text=“@={fieldName}”
而不是android:text=“@{fieldName}”
。
您的模型类可能如下所示:
public class BindingViewModel extends BaseObservable {
public Double inr = 0.0;
public Double dollar = 0.0;
@Bindable
public String getInrString() {
String inrString = String.valueOf(inr);
if (inrString.endsWith(".0"))
return inrString.substring(0, inrString.length() - 2);
return inrString;
}
public void setInrString(String inrString) {
if (inrString != null && !inrString.isEmpty()) {
double newInr = Double.parseDouble(inrString);
if (this.inr != newInr) {
this.inr = newInr;
dollar = inr * 0.014;
}
} else {
inr = 0.0;
dollar = 0.0;
}
notifyPropertyChanged(BR.dollarString);
}
@Bindable
public String getDollarString() {
String dollarString = String.valueOf(dollar);
if (dollarString.endsWith(".0"))
return dollarString.substring(0, dollarString.length() - 2);
return dollarString;
}
public void setDollarString(String dollarString) {
if (dollarString != null && !dollarString.isEmpty()) {
double newDollar = Double.parseDouble(dollarString);
if (this.dollar != newDollar) {
this.dollar = newDollar;
inr = dollar * 71.92;
}
} else {
inr = 0.0;
dollar = 0.0;
}
notifyPropertyChanged(BR.inrString);
}
}
然后您可以布局XML:
<layout>
<data>
<variable
name="vm"
type="com.BindingViewModel" />
</data>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="@+id/inr"
android:layout_width="108dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:ems="10"
android:inputType="number"
android:text="@={vm.inrString}"
android:selectAllOnFocus="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.17"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/dollar"
android:layout_width="108dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:ems="10"
android:inputType="number"
android:text="@={vm.dollarString}"
android:selectAllOnFocus="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/inr"
app:layout_constraintTop_toTopOf="parent" />
...
这种方法有效。那么,在这种情况下,
notifyPropertyChanged
如何不引起循环呢?只有当值来自用户输入时,它才会在内部触发第二个EditText的文本监视程序?@user3339689,当您更改EditText中的文本时,将调用setter方法,在我们的例子中,NotifyPropertyChange将调用另一个getter方法。因此,没有理由使用无限循环
BindingViewModel viewModel=new BindingViewModel();
binding.setVm(viewModel);