JetPack的导航组件看上去很有希望,但是我到了一个找不到实现自己想要的东西的地方。
让我们看一下示例应用程序屏幕:
该应用程序有一个主要活动,一个顶部的工具栏,一个底部的工具栏,并带有fab。 我面临着两个挑战,我想让它们以正确的方式进行。
1。我需要实现片段事务,以便允许基于用户交互来替换屏幕上的片段。 我可以想到并实现三种方法:
onFragmentAction
回调,并有活动来实现它。因此,基本上,当用户按下FragmentA
中的按钮时,我可以使用参数调用onFragmentAction
,这样该活动将触发并开始执行例如用FragmentB
代替它的交易Navigation
组件。虽然我已经尝试过了,而且看起来很简单,但是由于无法检索当前片段,我遇到了一个问题。ViewModel
,从片段中对其进行更新并在活动中进行观察。这将是回调的“替代” 2。由于FAB
在父活动中,因此在按下时,我需要能够与当前可见片段进行交互并执行操作。例如,在片段内的recyclerview中添加新项目。因此,基本上是一种在活动和片段之间进行交流的方法
我可以通过两种方法来做到这一点
Navigation
,那么我可以使用findFragmentById
并检索当前片段并运行公共方法来触发操作。 因此,如您所见,推荐的导航方法是使用新的“ Navigation”架构组件,但是,目前它缺少检索当前片段实例的方法,因此我不知道如何在活动和片段之间进行交流。
这可以通过shared ViewModel
来实现,但是在这里我有一个遗漏的地方:我知道可以使用共享的ViewModel进行片段到片段的通信。我认为,当片段对此有一些共同点时(例如主/细节方案)并共享相同的视图模型,这很有用。
但是,然后在活动和 ALL 片段之间进行交谈,如何使用共享的ViewModel
?每个片段都需要自己的复杂ViewModel。可能是GeneralViewModel
会在活动和所有片段中实例化的地方,还有常规的片段视图模型,因此每个片段中都有2个视图模型。
能够通过视图模型在片段和活动之间进行交谈,这将不需要发现活动片段,因为视图模型将提供所需的机制,并允许使用Navigation
组件。
很高兴收到任何信息。
稍后编辑。这是一些基于注释的示例代码。这是我的问题的解决方案吗?这样可以同时处理片段和父级活动之间的变化吗?
private GlobalViewModel ():ViewModel(){
var eventFromActivity:MutableLiveData<Event>
var eventFromFragment:MutableLiveData<Event>
fun setEventFromActivity(event:Event){
eventFromActivity.value = event
}
fun setEventFromFragment(event:Event){
eventFromFragment.value = event
}
}
然后参加我的活动
class HomeActivity: AppCompatActivity(){
onCreate{
viewModel = ViewModelProviders.of(this, factory)
.get(GlobalViewModel::class.java)
viewModel.eventsFromFragment.observe(){
//based on the Event values, could update toolbar title, could start
// new fragment, could show a dialog or snackbar
....
}
//when need to update the fragment do
viewModel.setEventFromActivity(event)
}
}
然后所有片段中都有类似的内容
class FragmentA:Fragment(){
onViewCreated(){
viewModel = ViewModelProviders.of(this, factory)
.get(GlobalViewModel::class.java)
viewModel.eventsFromActivity.observe(){
// based on Event value, trigger a fun from the fragment
....
}
viewModelFragment = ViewModelProviders.of(this, factory)
.get(FragmentAViewModel::class.java)
viewModelFragment.some.observe(){
....
}
//when need to update the activity do
viewModel.setEventFromFragment(event)
}
}