This is my first time posting here. Please forgive me for any formatting issues <3
I'm trying to implement two-way data binding to record the current BPM number. When I click the add BPM or sub BPM button, I can observe on the back-end that the bpm field in the View Model is getting updated, but the UI is not. I have my fragment, view model, and layout shown below. I appreciate any and all help I receive!
Fragment Layout
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="practiceSegViewModel"
type="com.example.drumpracticeorganizer.practiceseg.PracticeSegViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/practice_seg_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ececec">
<EditText
android:id="@+id/edit_text_bpm"
style="@style/fragment_add_practice_label"
android:hint="@string/bpm"
app:layout_constraintEnd_toEndOf="@+id/edit_text_type"
app:layout_constraintStart_toStartOf="@+id/edit_text_type"
app:layout_constraintTop_toBottomOf="@+id/spinner_practice_sub_category" />
<Button
android:id="@+id/button_sub_bpm"
style="@style/fragment_add_practice_button_bpm"
android:onClick="@{() -> practiceSegViewModel.onDecrementBpm()}"
android:text="@string/minus_sign"
app:layout_constraintEnd_toStartOf="@+id/edit_text_bpm_input"
app:layout_constraintTop_toBottomOf="@+id/edit_text_bpm" />
<Button
android:id="@+id/button_add_bpm"
style="@style/fragment_add_practice_button_bpm"
android:onClick="@{() -> practiceSegViewModel.onIncrementBpm()}"
android:text="@string/plus_sign"
app:layout_constraintStart_toEndOf="@+id/edit_text_bpm_input"
app:layout_constraintTop_toBottomOf="@+id/edit_text_bpm" />
<EditText
android:id="@+id/edit_text_bpm_input"
style="@style/fragment_add_practice_input"
android:layout_width="100dp"
android:gravity="center_horizontal"
android:inputType="number"
android:maxLength="3"
android:text="@={`` + practiceSegViewModel.practice.bpm}"
android:textAlignment="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/edit_text_bpm" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Fragment Class
class PracticeSegFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
setHasOptionsMenu(true)
val application = requireNotNull(this.activity).application
val dataSource = PracticeDatabase.getInstance(application).practiceDatabaseDao
val viewModelFactory = PracticeSegViewModelFactory(dataSource, application)
val practiceSegViewModel =
ViewModelProvider(this, viewModelFactory).get(PracticeSegViewModel::class.java)
val binding = DataBindingUtil.inflate<FragmentPracticeSegBinding>(
inflater,
R.layout.fragment_practice_seg,
container,
false
).apply {
this.practiceSegViewModel = practiceSegViewModel
this.lifecycleOwner = viewLifecycleOwner
}
return binding.root
}
}
View Model
class PracticeSegViewModel(datasource: PracticeDatabaseDao, application: Application) :
AndroidViewModel(application) {
private val _practice = MutableLiveData<PracticeEntity>().apply {
value = PracticeEntity(subCategory = "", category = "", bpm = 0, duration = "0")
}
val practice: LiveData<PracticeEntity>
get() = _practice
val dao: PracticeDatabaseDao = datasource
fun onSave() {
savePractice()
}
private fun savePractice() {
viewModelScope.launch { _practice.value?.let { dao.insert(it) } }
}
fun onIncrementBpm() {
_practice.value?.bpm?.let {
if (it < 300) {
_practice.value?.bpm = it.plus(1)
println(_practice.value?.bpm.toString())
}
}
}
fun onDecrementBpm() {
_practice.value?.bpm?.let {
if (it > 0) {
_practice.value?.bpm = it.minus(1)
println(_practice.value?.bpm.toString())
}
}
}
}