标签: android-livedata

是否应该始终在 ViewModel 中使用 livedata?

视图模型中字段的推荐模式似乎是:

val selected = MutableLiveData<Item>()

fun select(item: Item) {
    selected.value = item
}
Run Code Online (Sandbox Code Playgroud)

(顺便说一句,该selected字段不是私有的,这是正确的吗?)

但是如果我不需要订阅 ViewModel 字段中的更改怎么办?我只需要被动地将这个值拉到另一个片段中。

我的项目详细信息:

  • 一个 Activity 和一堆简单片段用导航组件相互替换
  • ViewModel 执行业务逻辑并将一些值从一个片段传递到另一个片段
  • 活动和片段有一个 ViewModel,没有看到拥有多个 ViewModel 的意义,因为它是相同的业务流程
  • 我更喜欢将一个值存储在一个片段中,并在下一个片段中访问它来替换当前的片段,而不是将其传递到一个包中并在每个片段中手动一次又一次地检索

视图模型:

private var amount = 0
fun setAmount(value: Int) { amount = value}
fun getAmount() = amount
Run Code Online (Sandbox Code Playgroud)

片段1:

bnd.button10.setOnClickListener { viewModel.setAmount(10) }
Run Code Online (Sandbox Code Playgroud)

片段2:

if(viewModel.getAmount() < 20) { bnd.textView.text = "less than 20" }
Run Code Online (Sandbox Code Playgroud)

这是一种有效的方法吗?或者有更好的吗?或者我应该只使用 LiveData 或 Flow?

也许我应该使用SavedStateHandle?它可以注入到 ViewModel 中吗?

android viewmodel android-livedata

2
推荐指数
1
解决办法
3096
查看次数

Kotlin,Android - 如何将 MutableLiveData&lt;MutableList&lt; Something &gt;&gt; 转换为 LiveData&lt;List&lt; Something &gt;&gt;

MutableLiveData<MutableList<object>>在我拥有并且想要创建的ViewModel 中LiveData<List<object>>,但我不知道如何ListMutableList.

这是我想做的:

class AppViewModel : ViewModel() {

    private val _tasks = MutableLiveData<MutableList<Task>>(mutableListOf())
    val tasks: LiveData<List<Task>> = _tasks
}
Run Code Online (Sandbox Code Playgroud)

(但我收到错误类型不匹配。必需:LiveData<List> 发现:MutableLiveData<MutableList>

当我将其更改val tasks: LiveData<List<Task>> = _tasksval tasks: LiveData<MutableList<Task>> = _tasks它时,它可以工作,但我希望List任务中的任务不可编辑

android list kotlin android-livedata mutablelist

2
推荐指数
1
解决办法
1282
查看次数

LiveData 是热的还是冷的?

我们知道StateFlow和SharedFlow很热门。

\n
\n

StateFlow 是一个热流\xe2\x80\x94,只要该流被收集\n或者垃圾收集根中存在对其的任何其他引用,它就会保留在内存中。

\n
\n
\n

SharedFlow 是一个热流,它向所有从其收集的使用者发送值。\n

\n
\n

水流本身是冷的。

\n
\n

流是类似于序列的冷流......

\n
\n

我有一个问题无法找到直接答案。LiveData 是热的还是冷的?

\n

android android-livedata kotlin-flow kotlin-stateflow kotlin-sharedflow

2
推荐指数
1
解决办法
2268
查看次数

更改 LiveData 时 DataBinding 不更新值

我希望当我按下按钮并将其写入textview. 然而,下面的代码将增加的值显示为 Log 但在屏幕上, in 的值textview没有改变。我不确定出了什么问题。如果您知道,请告诉我。

片段.kt

class SettingFragment : Fragment(), View.OnClickListener {

    companion object {
        fun newInstance() = SettingFragment()
        private val TAG = "SettingFragment"
    }

    private lateinit var viewModel: SettingViewModel
    private lateinit var binding: FragmentSettingBinding

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_setting, container, false)
        return binding.root
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProvider(this).get(SettingViewModel::class.java)
        binding.lifecycleOwner = this
        binding.button.setOnClickListener(this)
    }

    override fun onClick(v: View?) { …
Run Code Online (Sandbox Code Playgroud)

data-binding android kotlin android-databinding android-livedata

2
推荐指数
1
解决办法
731
查看次数

Android-Kotlin 中“by懒惰”有什么应用?

应该在哪些地方by lazy使用?

为什么要使用它?

如何让代码变得更好

例如:

val currentResult: MutableLiveData<String> by lazy {
          MutableLiveData<String>()
}
Run Code Online (Sandbox Code Playgroud)

android kotlin android-livedata

2
推荐指数
1
解决办法
4900
查看次数

从第二个片段访问时 ViewModel 数据丢失状态

我用于保存用户登录数据的 ViewModel 遇到问题。

用户登录后,我使用片段 A 中的用户数据更新此 ViewModel,但是当我尝试访问片段 B 中的数据时,我刚刚设置的数据字段始终为空。

当片段 B 初始化时,userLiveData 字段最初不会被观察到,但是,当我user从片段 B 触发对对象的更改时,会在片段 B 中正确观察到更改。看来我的 ViewModel 中字段的先前值永远不会到达片段B,但是新的价值观可以。

为了进行完整性检查,我创建了一个简单的字符串变量(甚至不是 LiveData 对象),将其设置为片段 A 中的值,然后,在导航到片段 BI 后打印该值:它每次都未初始化。就好像我注入到片段 B 中的 ViewModel 与我注入到片段 A 中的 ViewModel 完全分开。

我缺少什么导致片段 B 中的 ViewModel 观察最初不使用user片段 A 中设置的最后一个已知值触发?

片段A

class FragmentA : Fragment() {
    private val viewModel: LoginViewModel by viewModel()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        viewModel.user.observe(this, {
            it?.let {
                //Called successfully every time
                navigateToFragmentB()
            }
        })
        
        val mockUserData = User() …
Run Code Online (Sandbox Code Playgroud)

android mvvm android-fragments android-livedata android-viewmodel

2
推荐指数
1
解决办法
973
查看次数

2.6.0 版本后找不到 androidx.lifecycle.LiveDataReactiveStreams 类

我刚刚开始玩LiveData。我按照官方 Android文档导入不同的工件。一切都很好,直到我需要将其转换ObservableLiveData. 但LiveDataReactiveStreams没有找到。最终我减少了版本号,当我达到2.5.1时,我很惊讶它终于起作用了。

我做错什么了吗?还是谷歌方面有问题?

我找不到任何与此相关的报告问题。但我真的不知道我能做些什么不同的事情......

我尝试手动导入它。然后我用了android.arch.lifecycle.LiveDataReactiveStreams. 这确实有效,但我应该坚持下去,并将所有内容更改androidxandroid.arch不是真正的解决方案。

android rx-java android-livedata

2
推荐指数
1
解决办法
896
查看次数

Android架构组件:ViewModel如何观察存储库中的LiveData

我正在研究Android架构组件,我有点困惑.在示例中,他们使用存储库并声明ViewModel观察到存储库的数据源内的更改.我不明白数据源中的更改是如何推送到ViewModel的,因为我看不到ViewModel中的任何代码将它们订阅到存储库.类似地,片段观察ViewModel的LiveData,但它们实际上订阅了LiveData:

 // Observe product data
    model.getObservableProduct().observe(this, new Observer<ProductEntity>() {
        @Override
        public void onChanged(@Nullable ProductEntity productEntity) {
            model.setProduct(productEntity);
        }
    });
Run Code Online (Sandbox Code Playgroud)

我在ViewModels中看不到任何类型的订阅来观察存储库.我错过了什么吗?

android mvvm viewmodel android-livedata android-architecture-components

1
推荐指数
1
解决办法
2321
查看次数

使用PowerMockRunner测试LiveData

我的本地单元测试始终使用LiveData。通常,当您尝试在MutableLiveData上设置值时,会得到

java.lang.RuntimeException: Method getMainLooper in android.os.Looper not mocked.
Run Code Online (Sandbox Code Playgroud)

因为本地JVM无法访问Android框架。我使用以下方法修复了该问题:

@get:Rule
val rule = InstantTaskExecutorRule()
Run Code Online (Sandbox Code Playgroud)

一切都很好,直到我不得不使用PowerMockito模拟来自Google Play库的静态方法。自从我添加

@RunWith(PowerMockRunner::class)
@PrepareForTest(Tasks::class)
Run Code Online (Sandbox Code Playgroud)

在我的测试类声明之上,我开始再次得到这个Looper not模拟错误。我之前在MockitoJUnitRunner中使用了此规则,一切都很好。

android kotlin powermockito android-livedata

1
推荐指数
1
解决办法
557
查看次数

Android-根据ViewModel中的选定项更改过滤LiveData列表

我的一个片段具有一个AndroidViewModel,其中包含一个LiveData列表,而另一个LiveData列表的选定项具有另一个属性。以下是我正在谈论的示例:

class TeamViewModel(app: Application): AndroidViewMode(app) {
    ...

    val selectedTeam = MutableLiveData<Team>()

    val allTeams: LiveData<List<Team>>
        get() = repository.getAllTeams().toLiveData()

    val allPlayers: LiveData<List<Player>>
        get() = repository.getAllPlayers().toLiveData()

    ...
}
Run Code Online (Sandbox Code Playgroud)

注意:返回一个RxJava Flowable List,然后我通过`.toLiveData将其转换为LiveData List getAllTeamsgetAllPlayers

目前,allPlayers代表所有团队的所有球员。我想这样做,以便每当selectedTeam更改值时,它allPlayers就会被过滤掉,只显示来自的玩家selectedTeam

我尝试过的是allPlayers像这样直接过滤:

val allPlayers: LiveData<List<Player>>
    get() = repository.getAllPlayers()
                .flatMap { list -> Flowable.fromIterable(list)
                    .filter {
                        player -> player.team == selectedTeam.value?.team
                    }
                }
                .toList()
                .toFlowable()
                .toLiveData()
Run Code Online (Sandbox Code Playgroud)

但是,您可能会猜到也可能不会猜到,allPlayers无论何时selectedTeam发生更改,它都不会更新过滤器。

反正是有动态改变过滤器allPlayers,只要selectedTeam改变?

编辑

感谢@EpicPandaForce,我得出的最终解决方案如下: …

android kotlin android-livedata

1
推荐指数
1
解决办法
1515
查看次数