在Android中使用Observable

问题描述 投票:27回答:4

我想实现一个带有许多片段的Navigation View,这些片段完全取决于MainActivity中定义的值。我知道MainActivity中的变量可以使用MainActivity中定义的方法从其他Fragments获取以获取值,但是这里的catch是MainActivity中变量的值可能会改变(在AsyncThread上运行)。现在,我要么更改代码,以便我的片段根据片段本身中的某些事件更新其值,或者使用SharedPreference。但我不想使用SharedPreferences,也不必多次检查值的变化。

我知道在RxJS中,我们使用Observable以异步方式运行,并以类似于传送带的方式工作。通过official docs : Observable进行的一些谷歌搜索证实了我对Android中可用类似内容的怀疑,但未找到任何正确的教程或如何实现它的解释。所以,我正在寻找一个简单的代码片段,它可以清楚地说明Observable在Android中是如何工作的,如果它是Async,并且它的基础类似于它的RxJS实现。 (不,我不想要RxJS实现)

测试用例:

MainActivity : int a, b (need observable for both variables)
Frag1 : int a1 , b1, a1changed(),b1changed()
Frag2 : int a2 , b2, a2Changed(), b2changed()

MainActivity包含整数,其值在更改时应反映在片段中的相应整数中,并在注意到的更改上调用每个片段的单独函数。

java android observable
4个回答
5
投票

Reactive不是Android的一部分,但你可能正在寻找这个库:https://github.com/JakeWharton/RxBinding

登录页面缺少一个介绍性示例,因此您必须查看javadoc。这篇文章应该给你一个良好的开端:How to create an Observable from OnClick Event Android?这是来自Matt的代码示例,可以帮助你入门

RxView.clicks(myButton)
    .subscribe(new Action1<Void>() {
        @Override
        public void call(Void aVoid) {
            /* do something */
        }
    });

1
投票

Android现在为您提供带有LiveData的ViewModels。视图模型绑定到具有生命周期(片段,活动)的对象,并且与该对象一样长。在您的情况下,您将创建一个绑定到行为的视图模型,所有碎片都可以访问该模型。

From the Android documentation

活动中的两个或多个片段需要相互通信是很常见的。想象一下master-detail片段的常见情况,其中有一个片段,用户从列表中选择一个项目,另一个片段显示所选项目的内容。这种情况永远不会是微不足道的,因为两个片段都需要定义一些接口描述,并且所有者活动必须将两者绑定在一起。此外,两个片段必须处理尚未创建或可见其他片段的场景。

可以使用ViewModel对象解决这个常见的痛点。这些片段可以使用其活动范围共享ViewModel来处理此通信

要使用视图模型在片段之间共享数据,您需要:

  1. 创建一个视图模型,它继承自ViewModel()并包含MutableLiveData-fields
  2. 通过调用ViewModelProviders.of(activity).get(YourViewModel :: class.java)从片段访问视图模型
  3. 通过为MutableLiveData-fields调用setValue来更改视图模型的值
  4. 通过调用.observe()注册MutableLiveData字段的更改

以下是关于如何使用ViewModel进行主 - 细节 - 视图的中央代码片段from the Android documentation

class SharedViewModel : ViewModel() {
    val selected = MutableLiveData<Item>()

    fun select(item: Item) {
        selected.value = item
    }
}

class MasterFragment : Fragment() {
    private lateinit var itemSelector: Selector
    private lateinit var model: SharedViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        model = activity?.run {
            ViewModelProviders.of(this).get(SharedViewModel::class.java)
        } ?: throw Exception("Invalid Activity")
        itemSelector.setOnClickListener { item ->
        // Update the UI
        }
    }
}

class DetailFragment : Fragment() {
    private lateinit var model: SharedViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        model = activity?.run {
            ViewModelProviders.of(this).get(SharedViewModel::class.java)
        } ?: throw Exception("Invalid Activity")
        model.selected.observe(this, Observer<Item> { item ->
            // Update the UI
        })
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.