如何使用Navigation Component在Fragment间传递BigDecimal类型参数
目前官方默认未提供BigDecimal的直接支持,可通过以下三种常用方案实现需求:
方案1:转换为String类型传递(最简便)
利用BigDecimal可通过无损字符串序列化的特性实现传递,无需额外配置:
- 导航图中定义参数类型为
String - 发送方调用
BigDecimal.toPlainString()将值转为字符串后传递,禁止使用toString()避免科学计数法导致的精度歧义 - 接收方拿到字符串后直接通过
BigDecimal(String)构造方法还原数值
示例代码:
// 发送页 val direction = FirstFragmentDirections.actionFirstToSecond(price.toPlainString()) findNavController().navigate(direction) // 接收页 val price = arguments?.getString("price")?.let { BigDecimal(it) }
方案2:通过自定义Parcelable包裹类传递
如果需要同时传递多个关联参数,可将BigDecimal封装进Parcelable类中传递,Navigation原生支持Parcelable类型参数:
- 自定义Parcelable数据类包裹BigDecimal字段,Kotlin可使用
@Parcelize注解快速实现
@Parcelize data class OrderInfo( val orderId: Long, val price: BigDecimal ) : Parcelable
- 导航图中定义参数类型为自定义Parcelable的全类名
- 收发双方直接操作Parcelable对象即可
方案3:自定义ArgType实现原生级支持(适合高频使用场景)
如果项目中多处需要传递BigDecimal参数,可通过自定义导航参数类型实现直接传递,无需每次手动转换:
- 继承
androidx.navigation.NavType实现BigDecimal的序列化反序列化逻辑:
class BigDecimalNavType : NavType<BigDecimal>(true) { override fun put(bundle: Bundle, key: String, value: BigDecimal) { bundle.putString(key, value.toPlainString()) } override fun get(bundle: Bundle, key: String): BigDecimal? { return bundle.getString(key)?.let { BigDecimal(it) } } override fun parseValue(value: String): BigDecimal { return BigDecimal(value) } }
- 导航图中定义参数时指定自定义类型的全类名:
<argument android:name="price" app:argType="com.your.package.BigDecimalNavType" />
- 后续使用时可直接传递/接收BigDecimal对象,Safe Args插件也会自动识别类型。
内容的提问来源于stack exchange,提问作者William Hu
相关产品推荐
相关产品推荐

