小编sun*_*son的帖子

Viewpager2 FragmentStateAdapter 中的“预期适配器在恢复状态时是‘新鲜’的”

当我尝试重新使用 Viewpager2 FragmentStateAdapter 时,出现此错误。我已经尝试将适配器设置为 null ,onDestroyView但这无济于事。

发生这种情况是因为我使用的是 Jetpack Navigation 库。当我离开片段时,视图被破坏。当我返回时,它被重新创建,我需要再次设置适配器。当我这样做时,适配器内部已经有片段,这会在restoreState().

android android-recyclerview android-viewpager2

9
推荐指数
0
解决办法
613
查看次数

带有 viewModelScope 的 Kotlin 协程单元测试流程集合

我想测试我的 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)

kotlin kotlin-coroutines

9
推荐指数
1
解决办法
4156
查看次数

具有双向数据绑定的自定义视图

我有一个自定义视图,它扩展了 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)

android kotlin android-databinding

7
推荐指数
1
解决办法
2189
查看次数

带有片段和Jetpack导航的Viewpager2:还原片段而不是重新创建它们

我有一个Viewpager2内部Fragment(称为HomeFragment)。那Viewpager本身也包含着Fragments。当我离开HomeFragment它的视图时,其视图将被破坏,而当我向后导航时,将重新创建该视图。现在,我设置的适配器Viewpager2HomeFragment过程中onViewCreated()。因此,当我回到该适配器将被重新创建HomeFragment,这也重新创建所有FragmentsViewpager2和当前项目重置为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

7
推荐指数
1
解决办法
303
查看次数

在 Android 发布版本中使用 Kotlin 反射sealedSubClasses 属性

当我尝试sealedSubClasses在 Kotlin 中使用 reified 类的属性时,它仅适用于我的调试,而不适用于我的发布版本。我想这是 ProGuard 的一个问题,但我不知道如何解决这个问题。我已经尝试将所有类保留在密封类所在的模块中,但我对此并不走运。该sealedSubClasses属性始终返回一个空列表。

reflection android kotlin

7
推荐指数
2
解决办法
413
查看次数

对使用 ViewModelScope.launch 延迟调用挂起函数的 ViewModel 方法进行单元测试

在我的文件中,ViewModel我有一个onTextChanged通过EditText. 在那里我用来viewModelScope.launch{}启动一个suspend函数。在该函数中我延迟了 500 毫秒。现在我该如何测试该onTextChanged方法?我尝试的所有操作总是导致测试在延迟完成之前完成。我尝试使用runBlockingTest,TestCoroutineDispatcherrunBlocking

文本观察器:

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)

android unit-testing kotlin-coroutines

6
推荐指数
1
解决办法
4047
查看次数

使用 Workmanager 进行 Hilt Instrumentation 测试无法正常工作

当我尝试在包含 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

6
推荐指数
1
解决办法
1464
查看次数

MotionLayout onSwipe 自动完成速度

有没有什么办法可以加速播放,当我停止中旬划动的动画MotionLayoutonSwipe过渡?目前它非常缓慢地过渡到开始或结束位置。

android android-motionlayout

5
推荐指数
1
解决办法
1172
查看次数