【问题标题】:Android two way binding with Integer type(Livedata)Android 整数类型的双向绑定(Livedata)
【发布时间】:2021-08-18 05:03:20
【问题描述】:

我在使用整数数据类型进行双向绑定时遇到了一些问题。

视图模型

var saleType: MutableLiveData<Int> = MutableLiveData(1)
var saleDetail: MutableLiveData<Int> = MutableLiveData(0)
var salePrice: MutableLiveData<Int> = MutableLiveData(0)
var saleRate: MutableLiveData<Int> = MutableLiveData(0)
var printAmount: MutableLiveData<Int> = MutableLiveData(1)

layout.xml

<data>
    <import type="com.package.utils.DataBindingConverters" />
    <variable
        name="viewModel"
        type="com.package.ViewModel" />
</data>
<com.google.android.material.textfield.TextInputEditText
   android:id="@+id/sale_detail_input"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_marginEnd="10dp"
   android:gravity="right"
   android:selectAllOnFocus="true"
   android:inputType="number"
   android:imeOptions="actionDone"
   android:singleLine="true"
   android:maxLines="1"
   app:inputContent="@={DataBindingConverters.convertIntegerToString(viewModel.saleDetail)}"
                        />

DataBindingConverters

class DataBindingConverters {

    companion object {
        @InverseMethod("convertStringToInteger")
        @JvmStatic
        fun convertStringToInteger(value: String): Int? {
            if (TextUtils.isEmpty(value) || !TextUtils.isDigitsOnly(value)) {
                return null
            }
            return value.toIntOrNull()
        }
        @InverseMethod("convertIntegerToString")
        @JvmStatic
        fun convertIntegerToString(value: Int?): String {
            return value?.toString() ?: ""
        }
    }

}

出现这样的错误

cannot find method convertIntegerToString(java.lang.String) in class com.package.utils.DataBindingConverters

我认为在双向绑定中处理 IntegerToString 的值会很好,但我得到一个找不到方法的错误。

在双向绑定中,有没有其他处理Integer的方法?

【问题讨论】:

    标签: android android-livedata two-way-binding


    【解决方案1】:

    我不知道app:inputContent 是做什么的,但是在TextInputEditText 上使用android:text 就足够了:

    <com.google.android.material.textfield.TextInputEditText
        ...
        android:text="@={ viewModel.salePriceString }"/>
    

    现在你想知道salePriceString 是什么。它应该是您的 2 路绑定 liveData,并且因为 android:text 需要 String,所以 salePriceString 键入将是 LiveData&lt;String&gt;。将您的 viewModel 修改为:

    val salePriceString = MutableLiveData<String?>(0.toString())
    

    现在,每次您在TextInputEditText 中编辑文本(通过用户输入)时,您的salePricesString 都会更新为新文本。并且无论何时您通过代码更新您的salePriceString,您的TextInputEditText 的文本都会相应更新。对于后一种情况,例如,如果您想将 salePriceString 更新为 500,您可以使用 salePriceString.postValue(500.toString())。如果您想在代码中从salePriceString 获取Int 值,只需执行salePriceString.value?.toIntOrNull()。

    接下来的步骤是可选的,但如果您想要一种方便的方法来获取 Int 值而不每次都使用 salePriceString.value?.toIntOrNull(),请进一步修改您的 viewModel:

    import androidx.lifecycle.Transformations
    ...
    
    val salePriceString = MutableLiveData<String?>(0.toString())
    // add conversion to LiveData<Int>
    val salePrice = Transformations.map(salePriceString) { priceString ->
        priceString?.toIntOrNull()
    }
    

    salePrice 现在包含Int 的值salePriceString,并在每次salePriceString 更改时自动更新。 salePrice 是一个LiveData,因此您可以像观察salePriceString 一样观察它,但您可以在salePrice 中准备好Int 值而不是salePriceString。

    最后一步是在代码中的某处观察salePrice,最符合逻辑的是在您的 viewModel 附加到的片段上:

    viewModel.salePrice.observe(this, {}) // this, or viewLifecycleOwner, depending on your use case
    

    你需要观察它,即使你对这个值什么也不做。这是因为Transformation.map 有点奇怪,由它创建的LiveData 不会“活”,除非存在观察者。这意味着在某些观察者观察到salePrice 之前,您不会从中获得任何价值,即salePrice.value 将始终是null。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-27
      • 1970-01-01
      • 2016-12-24
      • 1970-01-01
      • 2020-05-22
      • 1970-01-01
      • 2021-06-02
      相关资源
      最近更新 更多