首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将房间内的实体更新为isCompleted,并使用流问题获取所有数据

将房间内的实体更新为isCompleted,并使用流问题获取所有数据
EN

Stack Overflow用户
提问于 2022-10-20 14:30:35
回答 1查看 58关注 0票数 3

我有一个习惯应用程序,用户可以添加不同类型的新习惯,并将该习惯标记为已完成/不完整。

习惯片段显示了两种不同习惯类型的使用芯片“正”和“负”的习惯,因此当用户检查阳性芯片时,recyclerView就会得到与该负片相同的积极习惯和相同的东西。

,这是这个操作的工作原理.

这是我的DAO代码

代码语言:javascript
复制
@Query("SELECT * FROM HABIT_TABLE WHERE type = :type ORDER BY isCompleted ASC")
fun getAllHabitsByType(type: String): Flow<List<HabitEntity>>

@Query("UPDATE HABIT_TABLE SET isCompleted = :isCompleted WHERE habitId = :habitId")
suspend fun updateHabitByCompleted(habitId: Long, isCompleted: Boolean)

和我的存储库中,我从"HabitEntity“映射到"HabitModel”。因此,函数应该返回Flow>.

代码语言:javascript
复制
override fun getAllHabitsByType(type: HabitType): Flow<List<Habit>> {
    return channelFlow {
        dao.getAllHabitsByType(type.pathName).collect { habits ->
            send(habitMapper.map(habits))
        }
    }
}

override suspend fun updateHabitByCompleted(habit: Habit, isCompleted: Boolean) {
    dao.updateHabitByCompleted(habit.id, isCompleted)
}

我试图将从dao返回的流映射到回购函数中,然后将其发送到ViewModel ,但是它不能工作__,它应该收集数据,然后像上面的函数那样发送到ViewModel。,这是我以前做过的。

代码语言:javascript
复制
override fun getAllHabitsByType(type: HabitType): Flow<List<Habit>> {
    return flow { 
        dao.getAllHabitsByType(type.pathName).map { 
            emit(habitMapper.map(it))
        }
    }
}

Ok,然后我收集ViewModel中的最新变化,并在RecyclerView中观察它们。这是我的ViewModel函数.

代码语言:javascript
复制
private val _habitsList = MutableLiveData<List<Habit>>()
val habitsList: LiveData<List<Habit>> get() = _habitsList

private var currentHabitType = HabitType.POSITIVE

private fun getHabitsByType(habitType: HabitType) {
    viewModelScope.launch {
        repository.getAllHabitsByType(habitType).collectLatest {
            _habitsList.postValue(it)
        }
    }
}

override fun updateHabitByCompleted(habit: Habit, isCompleted: Boolean) {
    viewModelScope.launch {
        repository.updateHabitByCompleted(habit, isCompleted)
        getHabitsByType(currentHabitType)
    }
}

fun onChipTypeClick(habitType: HabitType) {
    currentHabitType = habitType
    getHabitsByType(habitType)
}

,这是我的HabitsFragment.

代码语言:javascript
复制
lateinit var habitsAdapter: HabitsAdapter

private fun initRecyclerVIew() {
    habitsAdapter = HabitsAdapter(emptyList(), viewModel)
    binding.habitsRecyclerView.adapter = habitsAdapter
}

private fun observeEvents() {
    viewModel.apply {
        ....
        habitsList.observe(viewLifecycleOwner) {
            habitsAdapter.setItems(it)
        }
    }
}

在习惯片段中使用XML代码

代码语言:javascript
复制
<data>

    <variable
        name="viewModel"
        type="com.moataz.mohareb.presentation.habits.viewmodel.HabitsViewModel" />

    <variable
        name="habitType"
        type="com.moataz.mohareb.core.enums.HabitType" />
</data>

<com.google.android.material.chip.ChipGroup
    style="@style/Widget.Material3.Chip.Suggestion"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:selectionRequired="true"
    app:singleSelection="true">

     <com.google.android.material.chip.Chip
         style="@style/ChipStyle"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:checked="true"
         android:onClick="@{() -> viewModel.onChipTypeClick(habitTYpe.POSITIVE)}"
         android:text="@string/good_habit"
         app:chipStrokeColor="@android:color/transparent" />

     <com.google.android.material.chip.Chip
         style="@style/ChipStyle"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:onClick="@{() -> viewModel.onChipTypeClick(habitTYpe.NEGATIVE)}"
         android:text="@string/bad_habit"
         app:chipStrokeColor="@android:color/transparent" />
</com.google.android.material.chip.ChipGroup>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/habits_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="6dp"
        android:orientation="vertical"
        android:overScrollMode="never"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/horizontal_chips_scroll_view"
        tools:listitem="@layout/item_habit" />

--这里是视图的代码--在习惯中单击CheckBox完成时更改了使用数据库.

代码语言:javascript
复制
    @BindingAdapter(value = ["app:changeTextStatue"])
    fun changeTextStatue(textView: TextView, isCompleted: Boolean) {
        if (isCompleted) {
            textView.paintFlags = textView.paintFlags or android.graphics.Paint.STRIKE_THRU_TEXT_FLAG
        } else {
            textView.paintFlags =
                textView.paintFlags and android.graphics.Paint.STRIKE_THRU_TEXT_FLAG.inv()
        }
    }

   @BindingAdapter(value = ["app:changeCheckBoxStatue"])
   fun changeCheckBoxStatue(checkBox: CheckBox, isCompleted: Boolean) {
        checkBox.isChecked = isCompleted == true
    }

我遇到的问题

当我选择第一个芯片显示数据并将其标记为已完成或未完成时,它工作正常,数据更新没有任何问题。请参阅此视频plz以充分了解https://youtube.com/shorts/bdRd70Me5nk?feature=share

如果我想从第一个芯片转移到另一个芯片,得到不同的习惯类型,而不完成任何习惯,它也工作得很好。https://youtube.com/shorts/t0Ma0BAE_Tw?feature=share

,如果我想将一个习惯标记为已完成,并希望从芯片好习惯转移到芯片坏习惯,该怎么办?而且,如果我已经养成了习惯,并想搬到另一个芯片。以下是这两种情况下的问题。RecycleView执行一个非常奇怪的蜂窝过程。 https://www.youtube.com/shorts/6juhhWxq6_Y

--我已经尝试搜索这个问题4天了,但是我没有找到任何有用的解决方案,也没有找到任何能让我完全理解我的问题的解决方案。

注意:

  • I尝试使用道中的"@ update“查询来更新实体,也出现了同样的问题。
  • 我还尝试从(流到挂起)更改getAllHabitsByType函数,并且在将习惯从notCompleted更改为已完成并移动到另一个芯片时,没有任何问题,但当然,当更新习惯状态以更新回收视图时,我需要再次调用getAllHabits getAllHabitsByType,而当从另一个片段添加新习惯时,我需要流到添加新习惯的时候,获得对回收视图的更新**

下面是我在github上的项目源代码,以充分了解我的代码https://github.com/MoatazBadawy/Mohareb

谢谢你,

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-20 16:16:44

我的应用程序中基本上有相同类型的UI,所以肯定有一种方法。

我认为channelFlow是主要的罪魁祸首,但也有大量的回调使得确定列表中的项目的垃圾邮件到底是什么而变得复杂。

代码语言:javascript
复制
override fun getAllHabitsByType(type: HabitType): Flow<List<Habit>> {
    return dao.getAllHabitsByType(type.pathName).map { habits ->
        habitMapper.map(habits)
    }
}

这绝对是可行的。

LiveData/Flow的主要优点是您不需要手动更新它,而是自动更新它。没有/可以不需要调用getHabitsByType。您只需要输入Flow/LiveData就可以了。

代码语言:javascript
复制
private val currentHabitType = MutableStateFlow(HabitType.POSITIVE)

private val _habitsList = currentHabitType.flatMapLatest { type ->
    repository.getAllHabitsByType(type)
}

val habitsList: LiveData<List<Habit>> get() = _habitsList.asLiveData()

这应该是您所需要的,包括数据库的自动更新和通过芯片进行的任何更改。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74141631

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档