如何使用Navigation组件向Fragment传递Enum类型的构造参数
不可以直接通过自定义构造参数的方式实现需求,核心原因如下:
- Android系统原生规则限制:Fragment发生系统重建(如屏幕旋转、低内存回收)时,系统只会调用其无参构造方法,自定义带参构造传入的参数会直接丢失,进而引发数据异常甚至崩溃,这也是Android官方一直不推荐使用带参构造向Fragment传参的核心原因。
- Navigation组件的实例化逻辑限制:Navigation内部通过反射调用XML中注册的Fragment的无参构造完成实例化,不会识别也不会调用你自定义的带Enum参数的构造,你定义的构造参数
nExampleFragmentParameter无法拿到跳转时传入的值,若未手动定义无参构造,还会直接引发实例化异常。
替代实现方案
如果你希望实现类似构造传参的调用体验,可以配合官方推荐的arguments机制实现工厂方法,示例如下:
class ExampleFragment : Fragment() { // 所需参数从arguments中读取 private val nExampleFragmentParameter: ExampleFragmentEnum by lazy { arguments?.getSerializable("exampleFragmentEnum") as ExampleFragmentEnum } companion object { // 工厂方法模拟构造传参写法 fun newInstance(param: ExampleFragmentEnum) = ExampleFragment().apply { arguments = Bundle().apply { putSerializable("exampleFragmentEnum", param) } } } }
配合Navigation跳转使用时,你现有的XML配置不需要修改,直接通过navigate方法传入Bundle即可,跳转代码示例:
val args = Bundle().apply { putSerializable("exampleFragmentEnum", ExampleFragmentEnum.TOP_NEWS) } Navigation.findNavController(mNavHostFragment).navigate(R.id.exampleFragment, args)
如果使用Navigation的Safe Args插件,还可以省去手动写Key、类型强转的步骤,使用更安全。
内容的提问来源于stack exchange,提问作者Vlad.mir
相关产品推荐
相关产品推荐

