Как показать полупрозрачное наложение загрузки поверх полного Composable

Я пытаюсь создать Composable, который обертывает другой Composable и отображаетCircularProgressBarкак наложение поверх него, покрывающее весь Composable.

Я почти заработал так, как хотел, см. Следующее к изображениям:

Начальное состояние

Состояние загрузки

Но, как видите, оверлей заполняет весь экран, а не только серый элемент и текстовое поле. Таким образом, кнопка выталкивается за пределы экрана.

Это мой текущий код:

      @Composable
fun LoadingBox(
    modifier: Modifier = Modifier,
    isLoading: Boolean = false,
    loadingText: String,
    content: @Composable() () -> Unit
) {
    Box(modifier = modifier
        .fillMaxWidth()
        .wrapContentHeight()
    ) {

        content()
        if (isLoading) {

            Surface(
                modifier = Modifier
                    .fillMaxSize()
                    .alpha(0.5f),
            ) {
                Column(
                    modifier = Modifier.fillMaxSize(),
                    verticalArrangement = Arrangement.Center,
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    CircularProgressIndicator()
                    Text(text = loadingText)
                }
            }
        }
    }
}

На скриншотах я указываю серое поле и текстовое поле в качестве параметра. Таким образом, наложение должно покрывать только серый цвет.LazyRowэлемент и текстовое поле.

Я уже наткнулся на внутренние меры , однако я не могу их использовать, поскольку приложение падает, когда я предоставляю LazyRow какcontentиз-за следующей ошибки:

      java.lang.IllegalStateException: Asking for intrinsic measurements of SubcomposeLayout layouts is not supported. This includes components that are built on top of SubcomposeLayout, such as lazy lists, BoxWithConstraints, TabRow, etc. To mitigate this:
- if intrinsic measurements are used to achieve 'match parent' sizing,, consider replacing the parent of the component with a custom layout which controls the order in which children are measured, making intrinsic measurement not needed

1 ответ

Вам следует:

  • добавлятьcontentAlignment = Alignment.Centerв родительском
  • УдалитьSurface
  • удалитьverticalArrangementвColumn
  • Добавить другойBoxкоторый можно заполнить полупрозрачным фоном

Что-то вроде:

      Box(modifier = modifier
    .fillMaxWidth(),
    contentAlignment = Alignment.Center,
) {

    content()
    if (isLoading) {
        Box(
            Modifier
                .matchParentSize()
                .background(Color.Gray.copy(alpha = 0.5f))

        )

        Column(
            modifier = Modifier.fillMaxWidth(),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            androidx.compose.material.CircularProgressIndicator()
            Text(text = loadingText)
        }

    }
}