【发布时间】:2020-12-28 13:45:15
【问题描述】:
概述:
您好。在我的应用程序中,用户可以在 EditText 中输入一个数字,然后将该数字用作生成从 1 到(用户输入的数字)的随机数的最大范围,然后应将其显示在 TextView 中。
问题:
当用户输入数字并按下按钮以在 TextView 中生成随机数时,它不会按预期工作。
例如:
最初,bonusNumber 的 LiveData 保持的值应该是 1(基于 init 块),但是当按下按钮时显示随机数 0 在按下按钮生成随机数后显示,而不是介于 1 和用户在 EditText 中输入的任何值之间的实际随机数。
代码:
视图模型:
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())
}
}
片段:
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
}
}
XML 视图(相关的):
<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" />
存储库:
class Repository {
/**
* Generate random number for the bonus number within a particular range set by user
*
* [maxNum]: the number that the user entered which acts as the max range for the random numbers
*/
fun generateBonusRandomNumber(maxNum: Int): Int {
val minNum = 1
// Adding 1[minNum] to the bound makes sure the number the person entered is inclusive
return Random().nextInt(((maxNum - minNum)) + minNum)
}
}
【问题讨论】:
-
你单独尝试过
generateBonusRandomNumber方法吗?您的逻辑是否按预期工作?然后尝试从片段观察 livedata(没有数据绑定),检查这是否有效。您的解决方案看起来不错。 -
我猜问题是您需要对编辑文本使用两种方式的数据绑定。这就是你可以做到的
android:text="@={your value}"。您可以拥有一个 string 类型的可观察变量,然后在调用此方法generateBonusRandomNumber时将其转换为 int 类型。每当用户更新 edittext 的值时,使用 @= 将更新您的变量值。 -
@AppDev 是对的。主要问题是您的
userBonusNumberlivedata 没有从布局中获取输入。即使您使用two way databinding,您也会公开 Immulable livedata 实例,这将阻止您的用户输入流动。我只是建议调用getRandomBonusNumber传递用户输入。无论如何,对于这种简单的用例,双向数据绑定也不是一个好习惯。 -
感谢大家的帮助。我将根据大家提出的建议为未来的用户发布答案。谢谢。保重。
标签: android kotlin mvvm android-livedata mutablelivedata