5

我有带有编辑文本和 2 个按钮的简单视图,我希望用户能够使用按钮将数量增加/减少 1,或者他可以在编辑文本小部件中手动写入数量,但这个值不能小于 0 并且大于10. 我正在使用带有 LiveData 和数据绑定的 MVVM 架构。目前在 ViewModel 我有两个变量_amount: Intamount:MutableLiveData. 我正在递增/递减_amount,然后为 MutableLiveData 分配新值。它正在工作,但我想知道是否有可能只使用一个变量来存储金额即获得相同的结果amount:MutableLiveData

视图模型
class TestActivityVM : ViewModel() {

    val amount = MutableLiveData<String>()
    private var _amount = 0

    init {
        amount.value = _amount.toString()
    }

    fun increment() {
        Log.d("TestActivityVM", "The amount is being increment, current value = ${amount.value}")

        //increment amount value by 1 if amount is less than 10
        if(_amount < 10) {
            amount.value = (++_amount).toString()
        }
    }

    fun decrement() {
        Log.d("TestActivityVM", "The amount is being decrement, current value = ${amount.value}")

        //decrement amount value by 1 if amount is greater than 0
        if(_amount > 0) {
            amount.value = (--_amount).toString()
        }
    }

    val amountValidator: TextWatcher = object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {
            _amount = if(s.toString().isEmpty()) 0 else s.toString().toInt()

            if(_amount > 10) {
                _amount = 10
                amount.value = _amount.toString()
            }
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
        }

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
        }

    }
}
活动
class TestActivity : AppCompatActivity() {

    private lateinit var testBinding: ActivityTestBinding
    private lateinit var testVM: TestActivityVM

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        testVM = ViewModelProviders.of(this).get(TestActivityVM::class.java)

        testBinding = DataBindingUtil.setContentView<ActivityTestBinding>(this, R.layout.activity_test).also {
            it.lifecycleOwner = this
            it.testVM = testVM
        }
    }
}
布局
<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>

        <variable
            name="testVM"
            type=".TestActivityVM" />
    </data>


    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".TestActivity">

        <Button
            android:id="@+id/minusBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginTop="16dp"
            android:text="-"
            android:onClick="@{() -> testVM.decrement()}"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/amountET" />

        <Button
            android:id="@+id/plusBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="8dp"
            android:text="+"
            android:onClick="@{() -> testVM.increment()}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/amountET" />

        <EditText
            android:id="@+id/amountET"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="8dp"
            android:ems="10"
            android:inputType="numberSigned"
            android:text="@={testVM.amount}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:addTextChangedListener="@{testVM.amountValidator}"/>

        <TextView
            android:id="@+id/textView4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginTop="84dp"
            android:text="Value of amount Live data:"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/minusBtn" />

        <TextView
            android:id="@+id/textView5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="32dp"
            android:layout_marginTop="8dp"
            android:text="@{testVM.amount}"
            android:textSize="24sp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView4" />

    </android.support.constraint.ConstraintLayout>
</layout>

4

3 回答 3

9

您可以使用amount.value来获取当前金额,而不是使用另一个变量。LiveData 应该是 Int,而不是 String,因为这是您要处理的数据类型。您的代码如下所示:

class TestActivityVM : ViewModel() {

    val amount = MutableLiveData<Int>().apply {
        value = 0
    }

    fun increment() {
        Log.d("TestActivityVM", "The amount is being increment, current value = ${amount.value}")

        //increment amount value by 1 if amount is less than 10
        amount.value?.let { a ->
            if (a < 10) {
                amount.value = a + 1
            }
        }
    }
于 2019-07-26T12:27:19.587 回答
0

更改金额以键入 MutableLiveData

fun increment() {
    Log.d("TestActivityVM", "The amount is being increment, current value = ${amount.value}")

    //increment amount value by 1 if amount is less than 10
    if(amount.value!! < 10) amount.value = amount.value!! +1
}

fun decrement() {
    Log.d("TestActivityVM", "The amount is being decrement, current value = ${amount.value}")

    //decrement amount value by 1 if amount is greater than 0
    if(amount.value!! > 0) {
        amount.value = amount.value!! -1
    }
}
于 2019-07-26T12:21:09.887 回答
0

理想的推荐方法是观察活动中的不可变 livedata 对象。与其从 VM 观察可变变量,不如创建一些返回 livedata 的方法,以便活动不应该修改可变对象。

还要避免在 VM 中使用 Android 组件/API 以使 VM 可测试。

于 2019-07-26T12:33:24.587 回答