当我尝试重新使用 Viewpager2 FragmentStateAdapter 时,出现此错误。我已经尝试将适配器设置为 null ,onDestroyView但这无济于事。
发生这种情况是因为我使用的是 Jetpack Navigation 库。当我离开片段时,视图被破坏。当我返回时,它被重新创建,我需要再次设置适配器。当我这样做时,适配器内部已经有片段,这会在restoreState().
我想测试我的 ViewModel 收集 Flow 的方法。在收集器内部,一个 LiveData 对象发生了变异,我想最后检查一下。这大致是设置的样子:
//Outside viewmodel
val f = flow { emit("Test") }.flowOn(Dispatchers.IO)
//Inside viewmodel
val liveData = MutableLiveData<String>()
fun action() {
viewModelScope.launch { privateAction() }
}
suspend fun privateAction() {
f.collect {
liveData.value = it
}
}
Run Code Online (Sandbox Code Playgroud)
当我现在action()在单元测试中调用该方法时,测试在收集流之前完成。这是测试的样子:
@Test
fun example() = runBlockingTest {
viewModel.action()
assertEquals(viewModel.liveData.value, "Test")
}
Run Code Online (Sandbox Code Playgroud)
我正在通过这个 Junit5 扩展以及 LiveData 的即时执行器扩展使用 TestCoroutineDispatcher:
class TestCoroutineDispatcherExtension : BeforeEachCallback, AfterEachCallback, ParameterResolver {
@SuppressLint("NewApi") // Only used in unit tests
override fun supportsParameter(parameterContext: ParameterContext?, extensionContext: ExtensionContext?): …Run Code Online (Sandbox Code Playgroud) 我有一个自定义视图,它扩展了 LinearLayout 并扩展了一个包含几个视图的布局。
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
xmlns:android="http://schemas.android.com/apk/res/android">
<EditText
android:id="@+id/voice_edittext"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:hint="Add answer here"
/>
<ImageButton
android:id="@+id/microphone_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_mic_black_24dp"
/>
<ImageButton
android:id="@+id/delete_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_cancel_black_24dp"
android:visibility="gone"
/>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
我现在想在使用此视图时双向绑定 Edittext 的文本值,如下所示:
<com.sunilson.quizcreator.presentation.views.EditTextWithVoiceInput
android:id="@+id/form_question"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
app:editTextValue="@={viewModel.observableText}"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Run Code Online (Sandbox Code Playgroud)
为此,我创建了一些绑定适配器
@BindingAdapter("editTextValueAttrChanged")
fun setListener(editTextWithVoiceInput: EditTextWithVoiceInput, listener: InverseBindingListener) {
editTextWithVoiceInput.voice_edittext.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
listener.onChange()
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun onTextChanged(p0: CharSequence?, p1: Int, …Run Code Online (Sandbox Code Playgroud) 我有一个Viewpager2内部Fragment(称为HomeFragment)。那Viewpager本身也包含着Fragments。当我离开HomeFragment它的视图时,其视图将被破坏,而当我向后导航时,将重新创建该视图。现在,我设置的适配器Viewpager2的HomeFragment过程中onViewCreated()。因此,当我回到该适配器将被重新创建HomeFragment,这也重新创建所有Fragments的Viewpager2和当前项目重置为0,如果我尝试重新使用的适配器,我实例化第一个创建的HomeFragment我得到一个异常,因为此检查位于FragmentStateAdapter:
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
checkArgument(mFragmentMaxLifecycleEnforcer == null);
Run Code Online (Sandbox Code Playgroud)
有人知道我在回溯时如何防止重新创建所有内容吗?否则,这是相当大的性能开销,并且会阻碍我的用户体验。
android android-fragments android-navigation android-recyclerview android-viewpager2
当我尝试sealedSubClasses在 Kotlin 中使用 reified 类的属性时,它仅适用于我的调试,而不适用于我的发布版本。我想这是 ProGuard 的一个问题,但我不知道如何解决这个问题。我已经尝试将所有类保留在密封类所在的模块中,但我对此并不走运。该sealedSubClasses属性始终返回一个空列表。
在我的文件中,ViewModel我有一个onTextChanged通过EditText. 在那里我用来viewModelScope.launch{}启动一个suspend函数。在该函数中我延迟了 500 毫秒。现在我该如何测试该onTextChanged方法?我尝试的所有操作总是导致测试在延迟完成之前完成。我尝试使用runBlockingTest,TestCoroutineDispatcher和runBlocking。
文本观察器:
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
searchJob = if (searchJob?.isActive == true) {
searchJob?.cancel()
viewModelScope.launch { search(s.toString()) }
} else {
viewModelScope.launch { search(s.toString()) }
}
}
Run Code Online (Sandbox Code Playgroud)
搜索方法:
private suspend fun search(query: String) {
delay(500)
searchUseCase(SearchParams(query)).fold({
}, {
})
}
Run Code Online (Sandbox Code Playgroud)
考试:
@Test
fun `Search is fired after 500ms when text is changed`() …Run Code Online (Sandbox Code Playgroud) 当我尝试在包含 WorkManager 的应用程序中运行 ActivityScenario 时,我在启动时收到以下错误:
java.lang.IllegalStateException: WorkManager is not initialized properly. You have explicitly disabled WorkManagerInitializer in your manifest, have not manually called WorkManager#initialize at this point, and your Application does not implement Configuration.Provider.
Run Code Online (Sandbox Code Playgroud)
使用工件WorkManagerTestInitHelper中的work-test也没有帮助。
WorkManager 的定义如下:
@Provides
@Singleton
fun provideWorkmanager(@ApplicationContext context: Context) = WorkManager.getInstance(context)
Run Code Online (Sandbox Code Playgroud)
这是我的测试自动取款机:
@HiltAndroidTest
@RunWith(AndroidJUnit4::class)
class LoginTest {
@get:Rule(order = 0)
var hiltRule = HiltAndroidRule(this)
@get:Rule(order = 1)
val activityRule = ActivityScenarioRule(MainActivity::class.java)
@Before
fun before() {
val context = InstrumentationRegistry.getInstrumentation().targetContext
val config = …Run Code Online (Sandbox Code Playgroud) android android-espresso android-instrumentation android-workmanager dagger-hilt
有没有什么办法可以加速播放,当我停止中旬划动的动画MotionLayout与onSwipe过渡?目前它非常缓慢地过渡到开始或结束位置。