我使用childFragmentManager在片段内显示一个对话框,或者使用supportFragmentManager在活动内显示一个对话框,在这个过程中,我想设置目标片段,如下所示:
val textSearchDialog = TextSearchDialogFragment.newInstance()
textSearchDialog.setTargetFragment(PlaceSearchFragment@this, 0)
但在运行该代码时,我得到了一个错误:
java.lang.非法状态异常:片段文本搜索对话片段{b7fce67#0 0}声明不属于此FragmentManager的目标片段PlaceSearch片段{f87414#0 id=0x7f080078}!
使用viewmodel和fragment ktx,您可以在父片段和子片段之间托管一个共享viewmodel,因此,您可以将viewmodel存储在父片段中,而不是让您的活动包含viewmodel的实例并存储数据,直到该活动完成,这样,当您弹出实例化viewmodel的片段时,viewmodel将被清除
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.2.1'
class ParentFragment:Fragment() {
private val model: SharedViewModel by viewModels()
}
class ChildFragment:Fragment(){
private val model: SharedViewModel by viewModels ({requireParentFragment()})
}
因此,这样做将在父片段中托管sharedviewmodel,并且依赖于该父片段的子片段将访问相同的sharedviewmodel实例,当您弹出(即销毁片段)时,您的onCleared()
方法将在您的viewmodel中激发,该shareviewmodel以及它的所有数据都将被清除。
这样,您就没有您的Mainactive来包含片段共享的所有数据,并且您不需要在每次离开使用SharedViewModel
的片段时清除该数据
现在在alpha中,您可以使用视图模型在导航之间传递数据,该视图模型将保存导航之间的数据,假设您想在片段B和片段A之间共享数据,现在您只需两行即可完成
https://developer.android.com/guide/navigation/navigation-programmatic#returning_a_result
详细说明公认的答案:
(1)创建一个共享视图模型,用于在该活动中的片段之间共享数据。
public class SharedViewModel extends ViewModel {
private final MutableLiveData<Double> aDouble = new MutableLiveData<>();
public void setDouble(Double aDouble) {
this.aDouble.setValue(aDouble);
}
public LiveData<Double> getDouble() {
return aDouble;
}
}
(2) 将要访问的数据存储在视图模型中。注意视图模型(getActivity)的范围。
SharedViewModel svm =ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
svm.setDouble(someDouble);
(3) 让片段实现对话框的回调接口,并在不设置目标片段的情况下加载对话框。
fragment.setOnDialogSubmitListener(this);
fragment.show(getActivity().getSupportFragmentManager(), TAG);
(4) 在对话框内检索数据。
SharedViewModel svm =ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
svm.getDouble().observe(this, new Observer<Double>() {
@Override
public void onChanged(Double aDouble) {
// do what ever with aDouble
}
});
更新:作为Navigation 2.3.0的一部分,Navigation添加了对返回结果的明确支持,其中有一个关于从对话框目标返回结果的特定部分,作为使用共享ViewModel的替代方法。
上一个答案:
在Fragments与导航架构组件之间进行通信的推荐模式是通过共享的ViewModel
-一个ViewModel
,它位于活动级别,通过使用ViewModelProvider(getActive())
检索ViewModel
来实现
根据文件,这提供了许多好处:
SharedViewModel
合约之外,片段不需要相互了解。如果其中一个片段消失,另一个会照常工作。通过使用导航图范围的ViewModel,您还可以在比整个活动更小的范围内共享ViewModels。
是否可以将新的导航架构组件与DialogFragment一起使用?我必须创建自定义导航器吗? 我很乐意将它们与导航图中的新功能结合使用。
我想在新用户登录时设置用户名和图片。我已经尝试过使用findViewById(),但是当我设置值“navHeaderName.setText(user_name);”时它给了我空指针异常。
我正在创建一个Android应用程序(Java),并第一次使用导航组件和Hilt。在导航编辑器中,我正在创建目标,并看到我创建的已用@AndroidEntryPoint注释的片段现在显示为“Hilt_”片段名称。现在我的应用程序无法构建,因为编译器正在寻找一个具有“Hilt_”片段名称而不仅仅是片段名称的构造函数。例如:我的片段名为Home片段,但在导航编辑器中它被称为Hilt_HomeFragm
我正在我的应用程序中尝试导航架构组件。早些时候,我使用片段事务来实现以下功能。基本上,我想从导航。 碎片- 如果我正在使用导航组件并尝试 然后结果是FragmentA被FragmentB替换并且背景片段不可见。 我想知道一个解决方案,如果导航架构组件允许的话。 附言:我听说过嵌套导航主机,但从内部使用它好吗。 更新: FragmentB将有进一步交易的行动,例如: 碎片- 当用户按下后退按钮时,片
到目前为止,我已经成功地导航到对话框并仅使用导航组件返回。问题是,我必须在对话框中做一些事情,并将结果返回到调用对话框的片段。 一种方法是使用共享viewmodel。但我必须使用。(活动)这让我的应用程序占用了一个单独的内存,即使我不再需要它。 另一种方法是覆盖show(framentManager, id)方法,访问片段管理器并从中访问先前的片段,然后将其设置为目标片段。我以前使用过目标片段方法
我正在我的应用程序中使用导航组件。我试图在单击操作栏图标时导航到片段,但它不起作用。以下是我的代码: 操作菜单。xml nav_主机。xml 主要活动。Java语言 这种方法不起作用-我如何导航?