0

我正在学习使用以下示例中的数据绑定:

https://github.com/ResoCoder/databinding-with-livedata-tutorial

特别是,我在使用以下代码时遇到了问题:

https://github.com/ResoCoder/databinding-with-livedata-tutorial/blob/master/app/src/main/java/com/resocoder/databinding/MainActivity.kt

第 29 行有一个 Toast:

Toast.makeText(this, it, Toast.LENGTH_SHORT).show()

如果以编程方式更改了 editTextContent,则会调用两次 toast。您可以通过按下标记为“SELECT RANDOM FRUIT FROM EDITTEXT”的按钮重现此行为

在这个例子中,两次调用观察者是浪费的,因为它显示了两次吐司,但在我的应用程序中,它给用户带来了一个严重的问题,因为如果数据以编程方式与用户发生变化,我会执行不同的操作。

我尝试通过将状态标记为程序性更改来缓解问题,但是在我的代码完成之后会出现无关的第二次调用。调用看起来好像用户正在编辑文本,所以我的程序执行操作就像用户输入数据一样。我看不出有什么方法可以区分无关调用和用户输入数据之间的区别。

请不要建议我隐藏条目的值,如果它没有改变,请忽略无关的调用。有一个合法的用例,用户在字段中输入完全相同的值。

理想情况下,找到无关呼叫的原因并消除它是解决问题和提高效率的最佳方式。不太理想的是一种解决方法,因此我可以忽略第二次调用,以便我的代码正常工作。

我怀疑这与设置适配器有关,或者可能与我设置观察者的时间/地点有关,但这是一个猜测。

谢谢。

4

1 回答 1

0
  • 这是我如何做到的结果
  • GIFimgur提供支持

动图 ==> 你怎么做

  1. 实现我的库的core_android 模块,当然不是整个库,也不是模块只是针对那个问题,但它包含了一个解决这个问题的方法,正如你在上面的 gif 中看到的那样。

  2. 在activity_main.xml

<!-- use the below 2 attributes
1st one ensures single trigger & 2nd one to distinguish the change -->
<EditText
    editText_textTwoWay="@={viewModel.mutableLiveDataEditTextContent}"
    editText_textTwoWay_enableDistinguishChangeCauser="@{true}"/>
  1. 在 MainActivity.kt
// inside onCreate()

// for dynamic change -> on button click
button.setOnClickListener {
    viewModel.mutableLiveDataEditTextContent.value = "Hello"
}

// for observing the change -> observe live data
viewModel.mutableLiveDataEditTextContent.observe(this, Observer {
    val isUserInputChangeNotDynamicallyChanged = binding.editText
        .getTag(R.id.editText_textTwoWay_isUserInputChangeNotDynamicallyChanged) as? Boolean
    val prefixMsg = when (isUserInputChangeNotDynamicallyChanged) {
        true -> {
            "User Change -> "
        }
        false -> {
            "Dynamic Change -> "
        }
        null -> {
            "UNKNOWN Change -> "
        }
    }
    val msg = prefixMsg + it.toStringOrEmpty()
    toast(msg) // extension fun for showing a Toast
    logError(msg) // to ensure invocation is done once isa.
})
于 2020-01-16T15:06:32.670 回答