我有一个片段等待来自 args 的整数。代码本身工作正常,但是当我想为此片段编写 UI 测试时,它给了我一个
java.lang.NullPointerException: null cannot be cast to non-null type kotlin.Int at androidx.navigation.NavType$Companion$IntType$1.get(NavType.kt:320) at androidx.navigation.NavType$Companion$IntType$1.get(NavType.kt:310) at androidx.navigation.NavArgument.verify(NavArgument.kt:76) at androidx.navigation.NavDestination.addInDefaultArgs(NavDestination.kt:603) at androidx.navigation.NavController.navigate(NavController.kt:1855) at androidx.navigation.NavController.handleDeepLink(NavController.kt:1414) at androidx.navigation.testing.TestNavHostController.setCurrentDestination(TestNavHostController.kt:51) at androidx.navigation.testing.TestNavHostController.setCurrentDestination$default(TestNavHostController.kt:47) at com.wolfpackdigital.extrakarte.base.BaseUITest.setupNavigation(BaseUITest.kt:130)`
The line which this refers to is
`navController.setCurrentDestination(R.id.MyFragment)
我像这样初始化我的场景:
val bundle = bundleOf(
"myParam" to 3
)
scenario = launchFragmentInContainer(themeResId = R.style.AppTheme, fragmentArgs = bundle)
对于所有其他类型的参数,它都可以工作(字符串,自定义数据模型),但对于整数,它不与我合作。
有什么想法吗?
您还没有提供您的
launchFragmentInContainer
实现,但我会根据我当前的设置和片段经验来回答。这是我的实现(请注意,我们正在使用 Hilt,但它应该类似)。
inline fun <reified T : Fragment> launchFragmentInHiltContainer(
fragmentArgs: Bundle? = null,
themeResId: Int = R.style.AppTheme,
fragmentFactory: FragmentFactory? = null,
crossinline action: T.() -> Unit = {}
) {
val mainActivityIntent = Intent.makeMainActivity(
ComponentName(
ApplicationProvider.getApplicationContext(),
HiltTestActivity::class.java
)
).putExtra(
"androidx.fragment.app.testing.FragmentScenario.EmptyFragmentActivity.THEME_EXTRAS_BUNDLE_KEY",
themeResId
)
ActivityScenario.launch<HiltTestActivity>(mainActivityIntent).onActivity { activity ->
fragmentFactory?.let {
activity.supportFragmentManager.fragmentFactory = it
}
val fragment = activity.supportFragmentManager.fragmentFactory.instantiate(
Preconditions.checkNotNull(T::class.java.classLoader),
T::class.java.name
)
fragment.arguments = fragmentArgs
activity.supportFragmentManager.beginTransaction()
.add(android.R.id.content, fragment, "")
.commitNow()
(fragment as T).action()
}
}
假设您想要启动一个名为
MyView
的特定片段,对于这个(以及每个片段),您应该有 MyViewArgs
(或类似)对象。然后就可以这样开始了:
val args = MyViewArgs(11111).toBundle()
HiltFragmentUtil.launchFragmentInHiltContainer<MyView>(args)
通过这种方式,您可以按照片段期望的确切方式提供参数,因此如果参数是 int,那么
MyViewArgs
将需要它作为 int