如何解决如何从EditText获取LiveData值并使用Kotlin在TextView中显示它? MVVM
概述:
问候。在我的应用程序中,用户可以在EditText中输入一个数字,然后将该数字用作生成从1到(用户输入的数字)的随机数的最大范围,然后应在TextView中显示该数字。
问题:
当用户输入数字并按下按钮以在TextView中生成随机数时,该数字将无法正常工作。
例如:
最初,LiveData为//div[@class='g']//div[@class='r']/a[contains(@href,'https://www.linkedin.com')]
保留的值应为 1 (基于bonusNumber
块),但是当按下按钮以显示按下按钮以生成随机数后,将显示随机数 0 ,而不是介于1和用户在EditText中输入的任何数字之间的实际随机数。
代码:
ViewModel:
init
片段:
class QuickPickViewModel : ViewModel() {
private val repository = Repository()
// LiveData for the number entered by the user
private var _userBonusNumber = MutableLiveData<Int>()
val userBonusNumber: LiveData<Int>
get() = _userBonusNumber
// LiveData for the actual result of the randomly generated bonus number
private var _bonusNumber = MutableLiveData<Int>()
val bonusNumber: LiveData<Int>
get() = _bonusNumber
init {
_userBonusNumber.value = 1
_bonusNumber.value = 1
}
fun getRandomBonusNumber() {
// Set the MutableLiveData to be displayed in the TextView,to the number the user entered
_bonusNumber.value = repository.generateBonusRandomNumber(_userBonusNumber.value!!.toInt())
}
}
XML视图(相关视图):
class QuickPickFragment : Fragment() {
private lateinit var binding: FragmentQuickPickBinding
private lateinit var viewModel: QuickPickViewModel
override fun onCreateView(
inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment using data binding
binding = DataBindingUtil.inflate(
inflater,R.layout.fragment_quick_pick,container,false
)
viewModel = ViewModelProvider(this).get(QuickPickViewModel::class.java)
binding.quickPickViewModel = viewModel
binding.lifecycleOwner = this
return binding.root
}
}
存储库:
<TextView
android:id="@+id/bonus_result_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@{String.valueOf(quickPickViewModel.bonusNumber)}"
android:textAllCaps="true"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/main_result_text_view" />
<EditText
android:id="@+id/bonus_set_edit_text"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="16dp"
android:ems="10"
android:hint="@string/enter_number_quick_pick_bonus_edit_text_hint"
android:importantForAutofill="no"
android:inputType="number"
android:text="@{String.valueOf(quickPickViewModel.userBonusNumber)}"
app:layout_constraintBaseline_toBaselineOf="@+id/bonus_set_title_text_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/bonus_set_title_text_view" />
<Button
android:id="@+id/button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:onClick="@{() -> quickPickViewModel.getRandomBonusNumber()}"
android:text="Generate"
android:textAllCaps="true"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
解决方法
解决方案:
如@AppDev的评论所建议,我可以使用双向数据绑定。
我之前的代码:
android:inputType="number"
android:text="@{String.valueOf(quickPickViewModel.userBonusNumber)}"
应更改为:
android:inputType="number"
android:text="@={quickPickViewModel.userBonusNumber}"
然后我的ViewModel应该更新如下:
class QuickPickViewModel : ViewModel() {
private val repository = Repository()
val userBonusNumber = MutableLiveData<String>()
private var _bonusNumber = MutableLiveData<Int>()
val bonusNumber: LiveData<Int>
get() = _bonusNumber
init {
userBonusNumber.value = "1"
_bonusNumber.value = 1
}
fun getRandomBonusNumber() {
_bonusNumber.value =
repository.generateBonusRandomNumber(userBonusNumber.value!!.toInt())
}
}
注意:
如评论中所述,两种方式的数据绑定并不总是安全的,因为它公开了具有写功能的实际MutableLiveData,而LiveData是只读且更安全的,但是在我的情况下,这并不适用,因为如前所述,数据是只读的,用户输入的数据不会更改。多亏了这些评论,我才意识到自己的错误。
因此,使用Fragment中的绑定对象从EditText捕获值,然后将TextView设置为该值,会更安全。但是,对于我上面的解决方案,我只是采用了两种方式进行数据绑定以显示其效果,因为Kotlin的在线示例并不多。
仅考虑未来的读者,我将保留所有这些信息。保重。