这可能来晚了,并以稍微不同的方式解决了问题,但我把它放在这里是因为我觉得这个问题需要一种在导航期间发送参数的方式,并以一种类型安全的方式发送到标称量级。
我的朋友是架构组件视图模型以非常有效的方式解决的问题之一。根据文档,在“片段之间共享数据”部分,我们将找到所使用的技术。本质上,这一切都是关于创建一个视图模型实例,该实例被附加到两个(或更多)导航到片段的封闭片段/活动的范围内。这样,它们将在导航到片段的整个生命周期中存活下来。
下面是一个小例子,我实际上是从我在生产中的一个应用程序中提取的。
-MainActivity
|-NavHostFragment
| |-FormFragment(Start destination)
| |-ResultFragment( navigated to fragment)
| |
以及用于在目标片段之间传输数据的 SharedViewModel。
查看模型代码
public class SharedViewModel extends ViewModel implements ResultFragment.ResultFragmentViewModel, FormFragment.FormFragmentViewModel {
public String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
} }
在 FormFragment 中。
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sharedViewModel = ((FormFragmentViewModel) ViewModelProviders.of(this.getActivity()).get(SharedViewModel.class));
}
public void onFabPressed( View view) {
String text = editText.getText().toString().trim();
if(text.matches("")) return ;
sharedViewModel.setName(text);
Navigation.findNavController(view).navigate(R.id.action_formFragment_to_resultFragment);
}
public interface FormFragmentViewModel {
public void setName(String string);
}
在结果片段中,
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sharedViewModel = ((ResultFragmentViewModel) ViewModelProviders.of(this.getActivity()).get(SharedViewModel.class));
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_result, container, false);
FloatingActionButton fab = view.findViewById(R.id.fab);
((TextView) view.findViewById(R.id.textview))
.setText(sharedViewModel.getName());
fab.setOnClickListener(
Navigation.createNavigateOnClickListener(R.id.action_global_formFragment)
);
return view;
}
public interface ResultFragmentViewModel {
public String getName();
}
在上面的代码中,重点应该放在发送到作为封闭活动的两个片段的 ViewModelProviders.of() 方法的范围上,因为它的生命周期比两个片段(FormFragment、ResultFragment)的生命周期都要长。在导航到目标 Fragment 之前保存我们希望发送到 viewmodel 中的目标 Fragment 的数据,知道我们将在目标 Fragment 中从 ViewModel 的同一实例中检索它。这些接口用于 android studio 的智能感知,从视图模型中抽象出(从开发人员的角度来看)不必要的方法,这些方法对应于它正在使用的片段。在这个设置中,甚至可以使用类似的东西将动作发送到目标片段委托模式通过将对象设置为在视图模型的目标片段中执行一次操作,然后导航到目标片段并在那里检索对象并将要执行的操作委托给它。我想在这个设置中补充一点,几乎不可能将String name
变量与 int 混淆。
希望这可以帮助。