Thread
#compose
    Colton Idle

    Colton Idle

    1 year ago
    I have a lazy column with a gradient background, and I want the gradient to be the entire height. BUT after I start scrolling I want to gradient to scroll up/off of the screen. Any Ideas on how to implement? I currently have a Box { GradientBackground() LazyColumn() } but the Gradient (of course) doesn't move up. Is there anything Col or LazyCol provide for this sort of thing? Kind of like a "first page background", and then a background for everything below the device height?
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    1 year ago
    Calculate an offset for the box background from the lazy list’s scroll state.
    Colton Idle

    Colton Idle

    1 year ago
    Box { GradientBackground() SolidBackground(offset = -screenHeight) LazyColumn() } and then LazyCol scroll state moves the SolidBackground offset towards a positive direction?
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    1 year ago
    i was thinking something like:
    Box(Modifier.background(Color.Magenta)) {
      GradientBackground(
        Modifier
          .fillMaxSize()
          .offset { IntOffset(0, -scrollState.value) }
      )
      LazyColumn(…)
    }
    Colton Idle

    Colton Idle

    1 year ago
    Ah. That actually is nicer. So the box is actually the magenta color and the gradient just scrolls out of the way. I like it. Will give it a try right after I deal with some navigation issues. Thanks for the extra set of eyes!
    Compose is like magic. I swear. It works great. Thanks for the tip @Zach Klippenstein (he/him) [MOD]
    Ashu

    Ashu

    1 year ago
    Just to make it a little more complex, how can we achieve the same gradient thing, but instead of the background, it applies to the content background. Like it happens in telegram where your chat message bubble have a gradient, top chat bubbles are let's say magenta in color and as you go down they become blue let's say. I am really fascinated by that.@Colton Idle @Zach Klippenstein (he/him) [MOD]
    Colton Idle

    Colton Idle

    1 year ago
    I think someone accomplished that in #compose channel. Try to search for it but I swear I saw it.
    Ashu

    Ashu

    1 year ago
    Cool thanks
    Colton Idle

    Colton Idle

    1 year ago
    @Zach Klippenstein (he/him) [MOD] so my requirements on this changed, and now after spending some time on this, I can't wrap my head around what the right solution to this is. Basically what I need to start with is a transparent box the size of the screen (not a gradient), and while I scroll up, then the solid magenta needs to come up from below. What I have "sorta" works, but the magenta doesn't come up soon enough, it comes up in the last portion of the scroll. This is what I have:
    val scrollState = rememberScrollState()
    Box(modifier = Modifier.fillMaxSize()
    ) {
        Box(
            Modifier.matchParentSize().offset { IntOffset(0, scrollState.maxValue - scrollState.value) }.background(Color.Magenta)
        )
        Column(
            horizontalAlignment = Alignment.CenterHorizontally,
            modifier =
            Modifier.fillMaxSize()
                    .verticalScroll(scrollState)
    Let me know if you have any other ideas for me as I feel like I'm missing something simple. Cheers
    "Solved" it by using boxWithConstraints (I'm never really happy when I use boxWithConstraints because I know it shouldn't just be used everywhere) but I'm not sure if there's some other way
    val scrollState = rememberScrollState()
    BoxWithConstraints(modifier = Modifier.fillMaxSize()) {
        val constraintBox = this@BoxWithConstraints
        Box(
            Modifier.matchParentSize()
                .offset {
                    IntOffset(
                        0,
                        if (constraintBox.maxHeight.roundToPx() -
                            scrollState.value >= 0)
                            constraintBox.maxHeight.roundToPx() -
                                scrollState.value
                        else 0)
                }
    Let me know if I'm overcomplicating things... but I will go with this for now. 😄
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    1 year ago
    You could do this with a custom layout as well, but this really isn’t that much code so if it works for you then great Since this is just a drawing effect, you could just draw the background yourself in a
    drawBehind
    modifier. That would eliminate the need for BwC and also only require a new draw pass on each scroll instead of a new composition + layout pass.
    Colton Idle

    Colton Idle

    1 year ago
    Haven't used drawBehind... Hm. Will give that a whirl. Just the kind of insight I was looking for. This screen is already doing a lot and showing a long lazy list and so I'm trying to optimize where possible. Thanks!
    :android-wave: hey zach, I went ahead and tried drawBehind, but not sure if I understand how I could do it without a BWC.
    Box(
        Modifier.matchParentSize()
            .drawBehind {
                drawRect(
                    color = Color.Magenta,
                    topLeft = Offset(size.width, -scrollState.value.toFloat()),
                    size = Size(size.width, size.height))
            }
    Maybe something is going over my head? or I've been staring at this for too long. lol
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    1 year ago
    Maybe the latter – if the left is at the
    size.width
    , the rectangle will always be off screen 😉 Also
    size
    has a default value that I think should work here. How about:
    .drawWithCache {
      // Don't trigger any more draw invalidations once scrolled past the first screen.
      val colorTop = derivedStateOf { (size.height - scrollState.value.toFloat()).coerceAtLeast(0f) }
      onDrawBehind {
        drawRect(
          color = Color.Magenta,
          topLeft = Offset(0f, colorTop)
        )
      }
    }
    Colton Idle

    Colton Idle

    1 year ago
    Hey Zach! That worked! Need to study that api a bit more since it is totally going over my head... didn't even hear about the drawWithCachen until your comment.