onebone/compose-collapsing-toolbar

Calculate toolbar height dynamically.

Opened this issue · 1 comments

Hi, I have a use case where my title can have a different length. What I am trying to achieve is to have the collapsing toolbar size dynamically calculated during composition.
I have introduced the var titleHeight = remember { mutableStateOf(0.0) } variable which is calculated in modifier like this

.onGloballyPositioned { textLayoutResultState.value = it.size.height }

  private fun CollapsingToolbarScope.ToolbarTitle(
      toolbarState: CollapsingToolbarScaffoldState,
      state: InstalledBaseDetailsState,
      installedBase: InstalledBase,
      textLayoutResultState: MutableState<Double>,
  ) {
      val textSize =
          (MIN_TITLE_TEXT_SIZE + (MAX_TITLE_TEXT_SIZE - MIN_TITLE_TEXT_SIZE) * toolbarState.toolbarState.progress).sp
      val startPadding =
          (MIN_TITLE_PADDING + (MAX_TITLE_PADDING - MIN_TITLE_PADDING) * (1 - toolbarState.toolbarState.progress)).dp
  
      Column(
          modifier = Modifier.Companion
              .background(color = colorResource(id = R.color.dark_orange))
              .road(Alignment.CenterStart, Alignment.BottomStart)
              .padding(
                  start = startPadding,
                  top = dimensionResource(id = R.dimen.grid_1_25x),
                  end = dimensionResource(id = R.dimen.grid_2x),
                  bottom = dimensionResource(id = R.dimen.grid_1x)
              )
              .onGloballyPositioned {
                  if ((it.size.height) > textLayoutResultState.value) {
                      textLayoutResultState.value = it.size.height
                  }
              }
      ) {
          Box(
              modifier = Modifier
                  .graphicsLayer {
                      alpha = toolbarState.toolbarState.progress
                      scaleX = toolbarState.toolbarState.progress
                      scaleY = toolbarState.toolbarState.progress
                  }
                  .height(
                      height = (SYSTEM_STATUS_HEIGHT * toolbarState.toolbarState.progress).dp,
                  )
  
          ) {
              SystemStatusSection(state.servicesStatus, installedBase)
          }
  
          Text(
              modifier = Modifier.fillMaxHeight(),
              //text = installedBase.name,
              text = "Very very very very very very long longy very very very long long ",
              style = headerTextStyle(toolbarState.toolbarState.progress),
              maxLines = headerMaxLines(toolbarState.toolbarState.progress),
              color = colorResource(id = R.color.black),
              fontSize = textSize,
              overflow = TextOverflow.Ellipsis,
          )
      }
  }
private fun CollapsingToolbarScope.CollapsingToolbar(
    toolbarState: CollapsingToolbarScaffoldState,
    state: InstalledBaseDetailsState,
    installedBase: InstalledBase,
    onBackTap: () -> Unit
) {
    val titleHeight = remember { mutableStateOf(0.0) }

    Box(
        modifier = Modifier
            .pin()
            .height(titleHeight.value.dp)
    )

    ToolbarTitle(toolbarState, state, installedBase, titleHeight)
    Box(
        modifier = Modifier
            .clip(CircleShape)
            .clickable(
                indication = rememberRipple(bounded = true),
                interactionSource = remember { MutableInteractionSource() },
                onClick = {
                    onBackTap()
                })
            .padding(dimensionResource(id = R.dimen.grid_2x))
    ) {
        Icon(
            painter = painterResource(id = R.drawable.ic_arrow_back),
            contentDescription = null,
            tint = colorResource(id = R.color.healthy_orange)
        )
    }
}

Current behaviour:

image

Intended behaviour:

image

The brown view is the one I measure during the composition. When I hardcode measured value then it works perfectly but when it is calculated then the progress value is wrongly calculated. The list can be manually scrolled and after that toolbar it rendered corectly.

Any ideas how to resolve that issue?

Is it correct that you want the toolbar to be measured again whenever the title has changed?