0

我已在我的应用程序中从使用 LiveData 切换到 StateFlow,并将其应用到数据绑定中。但是更改 StateFlow 的值后,UI 没有更新。根据我从StateFlow 文档中了解到的情况,我只需为valueStateFlow 的属性分配一个新值即可更新其消费者。

下面,我有一个时间字段,我使用MaterialTimePicker对话框更新值。selectedAlarm但是在我更改时间并为我的视图模型的属性 ( )分配一个新值后StateFlow,UI 不会针对新值进行更新。我不确定我的错误在哪里或缺少什么。

下面是我的AlarmFormFragment

@AndroidEntryPoint
class AlarmFormFragment : Fragment() {
    private val alarmsViewModel: AlarmsViewModel by activityViewModels()
    private var _binding: FragmentAlarmFormBinding? = null
    private val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentAlarmFormBinding.inflate(inflater, container, false)
        binding.alarmsViewModel = alarmsViewModel
        binding.lifecycleOwner = viewLifecycleOwner
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        setUpTimeField()
    }

    private fun setUpTimeField() {
        alarmsViewModel.selectedAlarm.value.let { alarm ->
            binding.llTimeField.setOnClickListener {
                // Create and then show time picker
                val picker =
                    MaterialTimePicker.Builder()
                        .setTimeFormat(TimeFormat.CLOCK_12H)
                        .setTitleText("Set Time")
                        .setHour(alarm.time.get(Calendar.HOUR_OF_DAY))
                        .setMinute(alarm.time.get(Calendar.MINUTE))
                        .build()

                picker.addOnPositiveButtonClickListener {
                    alarm.time.set(Calendar.HOUR_OF_DAY, picker.hour)
                    alarm.time.set(Calendar.MINUTE, picker.minute)
                    alarmsViewModel.selectedAlarm.value = alarm
                }

                picker.show(childFragmentManager, "TIME_INPUT_DIALOG")
            }
        }
    }
}

下面是 xml 文件AlarmFormFragment

<?xml version="1.0" encoding="utf-8"?>
<layout>
    <data>
        <import type="com.example.myclock.utilities.Utility" />
        <import type="com.example.myclock.utilities.SnoozeUtils"/>
        <variable
            name="alarmsViewModel"
            type="com.example.myclock.viewmodels.AlarmsViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        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"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".fragments.AlarmFormFragment">

        <!-- Form Fields -->
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <!-- Time Field -->
            <LinearLayout
                android:id="@+id/llTimeField"
                style="@style/FormFieldLayoutStyle">

                <TextView
                    style="@style/FormFieldTextStyle.Label"
                    android:text="@string/label_time" />

                <TextView
                    android:id="@+id/tvTime"
                    style="@style/FormFieldTextStyle.Value"
                    android:text="@{Utility.INSTANCE.timeToString(alarmsViewModel.selectedAlarm.value.time)}" />
            </LinearLayout>
        </LinearLayout>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

下面是我的AlarmsViewModel

@HiltViewModel
class AlarmsViewModel @Inject constructor(
    private val alarmsRepository: AlarmsRepository
) : ViewModel() {
    private val _alarms = MutableStateFlow<List<Alarm>>(emptyList())
    val alarms: StateFlow<List<Alarm>> get() = _alarms
    var selectedAlarm = MutableStateFlow(Alarm())

    ...
}

以下是数据类Alarm

@Parcelize
@Entity
class Alarm(
    @PrimaryKey(autoGenerate = true) val id: Int = 0,
    var time: Calendar = Calendar.getInstance(),
    ...
) : Parcelable {
    ...
}
4

0 回答 0