首页 > 解决方案 > 不能在同一个 Measurable 上多次调用 measure()

问题描述

我正在创建一个应用程序,它使用 Flickr api 使用 Pager 3 库逐页获取图像,并使用 Jetpack Compose 在屏幕上显示它。一切正常,直到它加载 4-5 页(看起来它是浮动的)。

我收到一个错误:

Process: com.peterstaranchuk.flickrclient, PID: 9843
    java.lang.IllegalStateException: measure() may not be called multiple times on the same Measurable
        at androidx.compose.ui.node.OuterMeasurablePlaceable.remeasure-BRTryo0(OuterMeasurablePlaceable.kt:86)
        at androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui_release(LayoutNode.kt:1236)
        at androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui_release$default(LayoutNode.kt:1232)
        at androidx.compose.ui.node.MeasureAndLayoutDelegate.doRemeasure-0kLqBqw(MeasureAndLayoutDelegate.kt:171)
        at androidx.compose.ui.node.MeasureAndLayoutDelegate.access$doRemeasure-0kLqBqw(MeasureAndLayoutDelegate.kt:38)
        at androidx.compose.ui.node.MeasureAndLayoutDelegate.measureAndLayout(MeasureAndLayoutDelegate.kt:207)
        at androidx.compose.ui.platform.AndroidComposeView.onMeasure(AndroidComposeView.android.kt:547)
        at android.view.View.measure(View.java:17430)

它没有指向我的代码中的某个地方,看起来它与 Jetpack compose 测量有关。

我检查了所有可用信息,但没有找到答案。可能有人有同样的问题?任何线索将不胜感激。

我的视图模型:

class SearchViewModel(
    private val interactor: SearchInteractor,
    private val photosPresentationMapper: PhotoPresentationMapper,
    eventSender: ScreenEventSender<SearchContract.Event>,
    dispatchers: DispatchersProvider
) : BaseViewModel<SearchContract.Event>(eventSender, dispatchers) {

    fun observePhotos(): Flow<PagingData<PhotoPresentation>> {
        return interactor.getPagedPhotos("nature")
            .flowOn(dispatchers.io)
            .catch { /*todo handle error state */
                Log.d("", it.message.toString())
            }
            .map {
                it.map {
                    photosPresentationMapper.map(it)
                }
            }
    }
}

屏幕可组合:

@Composable
    fun ScreenContent() {
        val lazyPhotoItems: LazyPagingItems<PhotoPresentation> = vm.observePhotos().collectAsLazyPagingItems()

        Column {
            Box(
                modifier = Modifier
                    .wrapContentSize(Alignment.Center)
                    .background(Color(ContextCompat.getColor(LocalContext.current, R.color.black60transparency)))
                    .padding(8.dp)
            ) {
                Row(
                    modifier = Modifier
                        .wrapContentSize()
                        .fillMaxWidth()
                        .clip(RoundedCornerShape(50))
                        .background(colorResource(id = R.color.search_field_background_color)),
                    verticalAlignment = Alignment.CenterVertically,
                    horizontalArrangement = Arrangement.Center
                ) {
                    Icon(
                        painterResource(id = R.drawable.ic_search_image),
                        contentDescription = stringResource(R.string.search_screen_magnifier_icon_content_description),
                        tint = Color.White
                    )
                    Text(
                        modifier = Modifier.padding(top = 8.dp, bottom = 8.dp, start = 4.dp),
                        text = stringResource(R.string.search_screen_search_field_text),
                        fontSize = 12.sp,

                        color = colorResource(id = R.color.search_field_text_color),
                        fontFamily = getFont(R.font.nunito_sans_extra_bold)
                    )
                }
            }

            LazyColumn (content = {
                items(lazyPhotoItems.itemCount, {
                    lazyPhotoItems[it]!!.id
                }) { index ->
                    ImageItem(lazyPhotoItems[index]!!)
                }
            }, modifier = Modifier.fillMaxSize())
        }
    }

我用:

//paging
    implementation "androidx.paging:paging-runtime:$paging_version"
    implementation "androidx.paging:paging-compose:$paging_compose_version"

与版本:

    compose_version = '1.0.1'
    paging_compose_version = "1.0.0-alpha12"

标签: android-jetpack-composeandroid-paging-3

解决方案


我建议你添加.cachedIn(viewModelScope) 看评论// Here

fun observePhotos(): Flow<PagingData<PhotoPresentation>> {
            return interactor.getPagedPhotos("nature")
                .cachedIn(viewModelScope) // Here
                .flowOn(dispatchers.io)
                .catch { /*todo handle error state */
                    Log.d("", it.message.toString())
                }
                .map {
                    it.map {
                        photosPresentationMapper.map(it)
                    }
                }
        }

推荐阅读