我想实现一个带有许多片段的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包含整数,其值在更改时应反映在片段中的相应整数中,并在注意到的更改上调用每个片段的单独函数。
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 */
}
});
Android现在为您提供带有LiveData的ViewModels。视图模型绑定到具有生命周期(片段,活动)的对象,并且与该对象一样长。在您的情况下,您将创建一个绑定到行为的视图模型,所有碎片都可以访问该模型。
From the Android documentation:
活动中的两个或多个片段需要相互通信是很常见的。想象一下master-detail片段的常见情况,其中有一个片段,用户从列表中选择一个项目,另一个片段显示所选项目的内容。这种情况永远不会是微不足道的,因为两个片段都需要定义一些接口描述,并且所有者活动必须将两者绑定在一起。此外,两个片段必须处理尚未创建或可见其他片段的场景。
可以使用ViewModel对象解决这个常见的痛点。这些片段可以使用其活动范围共享ViewModel来处理此通信
要使用视图模型在片段之间共享数据,您需要:
以下是关于如何使用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
})
}
}