双向数据绑定无限循环 [英] Two-way data-binding infinite loop

查看:161
本文介绍了双向数据绑定无限循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个物品清单.在每个项目的行中,我并排有2个EditText. EditText-2取决于EditText-1的值.此列表与HashMap<String, ItemValues>

I have a list of items. In each item's row I have 2 EditTexts side-by-side. EditText-2 depends on EditText-1's value. This list is bound with data-binding values in HashMap<String, ItemValues>

例如:

Total     _____1000____
Item A    __1__ __200__
Item B    __1__ __200__
Item C    __1__ __200__
Item D    __2__ __400__

第一个EditText是份额,第二个值是根据总计和份额计算得出的值.因此,在示例中,如果我更改任何1份额,则所有值都会更改.因此,在示例中显示的总股数= 1 + 1 + 1 + 2 =5.因此,每股数量= 1000/5 = 200,计算得出并显示在下一个EditText中.

First EditText is the share and the second value is its value calculated based on total and share. So, in example if I change any 1 share, all the values will be changed. So, shown in example total no of shares are = 1+1+1+2 = 5. So amount per share = 1000/5 = 200 and is calculated and shown in next EditText.

我已经将这种值与双向数据绑定进行了绑定,如下所示:

I have bound this values with two-way data binding like this:

因为这是一个double值,所以我为此添加了2个绑定适配器:

As, this is a double value, I have added 2 binding adapters for this like this:

@BindingAdapter("android:text")
public static void setShareValue(EditText editText, double share) {
    if (share != 0) {
        editText.setText(String.valueOf(share));
    } else {
        editText.setText("");
    }
}

@InverseBindingAdapter(attribute = "android:text")
public static double getShareValue(EditText editText) {
    String value = editText.getText().toString();
    if (!value.isEmpty()) {
        return Double.valueOf(value);
    } else
        return 0;
}

现在,要计算新值,我需要在更改任何份额值后重新计算整个事情.因此,我添加了android:onTextChagned方法来更新Calculations.但这让我陷入了无限循环.

Now, to calculate new values, I need to re-calculate whole thing after any share value is changed. So, I added android:onTextChagned method to update Calculations. But it gets me an infinite loop.

<EditText
    android:text="@={items[id].share}"
    android:onTextChanged="handler.needToUpdateCalculations"
    .... />

public void needToUpdateCalculations(CharSequence charSequence, int i, int i1, int i2) {
    updateCalculations();
}

这会产生infinete循环,因为当数据更改时,它会反弹到EditText,并且每个EditText都附加有onTextChanged,它将再次触发并且它将变得非常大-无限循环.

This gets an infinete loop because when data changes, it is rebound to the EditText, and each EditText has an onTextChanged attached it will fire again and it will get really large - infinite loop.

它还会更新自身的值,最终也会导致光标丢失.

It also updates the value of itself, ended up loosing the cursor as well.

我还尝试了其他几种方法,例如在聚焦时添加TextWatcher以及在聚焦时删除TextWatcher.但是至少它会自我更新,并且会丢失游标或无限循环.

I have also tried several other methods like adding TextWatcher when on focus and removing when losses focus. But at least it will update it self and will loose the cursor or infinite loop.

无法解决此问题.谢谢您调查这个问题.

Unable to figure this problem out. Thank you for looking into this problem.

我尝试了以下方法.但是,它不允许我输入.(句点).

I have tried with the below method. But, it doesn't allow me to enter . (period).

@BindingAdapter("android:text")
public static void setDoubleValue(EditText editText, double value) {
    DecimalFormat decimalFormat = new DecimalFormat("0.##");
    String newValue = decimalFormat.format(value);
    String currentText = editText.getText().toString();

    if (!currentText.equals(newValue)) {
        editText.setText("");
        editText.append(newValue);
    }
}

推荐答案

您所说的原因是正确的,并且肯定会造成无限循环.并且有一种方法可以解决这个问题的无限循环,Android官方提供了一种解决方法(但这并不是很明显.)(

The reason you stated is correct and it will make a infinite loop definitely. And there is a way to get out from the infinite loop of this problem, android official provided a way to do so (But it is not quite obvious.)(https://developer.android.com/topic/libraries/data-binding/index.html#custom_setters)

绑定适配器方法可以选择在其旧值中使用旧值 处理程序.采用旧值和新值的方法应具有所有旧值 属性值首先出现,然后是新值:

Binding adapter methods may optionally take the old values in their handlers. A method taking old and new values should have all old values for the attributes come first, followed by the new values:

    @BindingAdapter("android:paddingLeft")
    public static void setPaddingLeft(View view, int oldPadding, int newPadding) {
       if (oldPadding != newPadding) {
           view.setPadding(newPadding,
                           view.getPaddingTop(),
                           view.getPaddingRight(),
                           view.getPaddingBottom());
       }
    }

您可以使用旧值和新值的比较来有条件地调用setText函数.

You can use the old value and new value comparison to make the setText function called conditionally.

@BindingAdapter("android:text")
public static void setShareValue(EditText editText, double oldShare,double newShare) {
    if(oldShare != newShare)
    {
        if (newShare!= 0) {
            editText.setText(String.valueOf(newShare));
        } else {
            editText.setText("");
        }
    }
}

这篇关于双向数据绑定无限循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆