TransformingLazyColumnItemScope

@TransformingLazyColumnScopeMarker
sealed interface TransformingLazyColumnItemScope


Receiver scope being used by the item content parameter of TransformingLazyColumn.

Summary

Public functions

open Unit

Preserves the appearance of some content within an item, by preventing implicit access to the TransformingLazyColumnItemScope.

Modifier
Modifier.animateItem(
    fadeInSpec: FiniteAnimationSpec<Float>?,
    placementSpec: FiniteAnimationSpec<IntOffset>?,
    fadeOutSpec: FiniteAnimationSpec<Float>?
)

This modifier animates item appearance (fade in), disappearance (fade out) and placement changes (such as an item reordering).

Modifier
Modifier.transformedHeight(
    heightProvider: (measuredHeight: Int, scrollProgress: TransformingLazyColumnItemScrollProgress) -> Int
)

Applies the new height of the item depending on its scroll progress and measured height.

Public properties

TransformingLazyColumnItemScrollProgress?

Scroll progress of the item before height transformation is applied using Modifier.transformedHeight.

TransformingLazyColumnItemScrollProgress?

Scroll progress of the item before height transformation is applied using Modifier.transformedHeight.

Public functions

TransformExclusion

Added in 1.5.0-alpha07
@Composable
open fun TransformExclusion(content: @Composable TransformingLazyColumnItemScope.() -> Unit): Unit

Preserves the appearance of some content within an item, by preventing implicit access to the TransformingLazyColumnItemScope. Explicit use of LocalTransformingLazyColumnItemScope can still apply transformations to the item.

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.text.BasicText
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.unit.dp
import androidx.wear.compose.foundation.lazy.LocalTransformingLazyColumnItemScope
import androidx.wear.compose.foundation.lazy.TransformingLazyColumn
import androidx.wear.compose.material.Text

fun rainbowColor(progress: Float): Color {
    val hue = progress * 360f
    val saturation = 1f
    val value = 1f

    return Color(android.graphics.Color.HSVToColor(floatArrayOf(hue, saturation, value)))
}

// Create a Box that automatically transform when in a TransformingLazyColumn
val implicitTransformingBox: @Composable (String) -> Unit = { text ->
    val itemScope = LocalTransformingLazyColumnItemScope.current
    Box(
        Modifier.height(30.dp)
            .then(
                itemScope?.let {
                    with(it) {
                        Modifier.graphicsLayer {
                                val itemProgression = scrollProgress ?: return@graphicsLayer
                                val scale =
                                    (itemProgression.bottomOffsetFraction -
                                        max(itemProgression.topOffsetFraction, 0f)) /
                                        (itemProgression.bottomOffsetFraction -
                                            itemProgression.topOffsetFraction)
                                scaleX = scale
                            }
                            .drawBehind {
                                val colorProgress =
                                    scrollProgress?.let {
                                        (it.topOffsetFraction + it.bottomOffsetFraction) / 2f
                                    } ?: 0f
                                drawRect(rainbowColor(colorProgress))
                            }
                    }
                } ?: Modifier.background(Color.Green)
            ),
        contentAlignment = Alignment.Center
    ) {
        BasicText(text)
    }
}
TransformingLazyColumn {
    items(count = 10) { implicitTransformingBox("Before #$it") }
    // The middle 3 boxes will not auto-transform
    items(count = 3) { TransformExclusion { implicitTransformingBox("Middle #$it") } }
    items(count = 10) { implicitTransformingBox("After #$it") }
}
fun Modifier.animateItem(
    fadeInSpec: FiniteAnimationSpec<Float>? = spring(stiffness = Spring.StiffnessMediumLow),
    placementSpec: FiniteAnimationSpec<IntOffset>? = spring( stiffness = Spring.StiffnessMediumLow, visibilityThreshold = IntOffset.VisibilityThreshold ),
    fadeOutSpec: FiniteAnimationSpec<Float>? = spring(stiffness = Spring.StiffnessMediumLow)
): Modifier

This modifier animates item appearance (fade in), disappearance (fade out) and placement changes (such as an item reordering).

You should also provide a unique key via TransformingLazyColumnScope.item/ TransformingLazyColumnScope.items for this modifier to enable animations.

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.wear.compose.foundation.lazy.TransformingLazyColumn
import androidx.wear.compose.foundation.lazy.TransformingLazyColumnState
import androidx.wear.compose.foundation.lazy.rememberTransformingLazyColumnState
import androidx.wear.compose.material.Text

val state = rememberTransformingLazyColumnState()

var list by remember { mutableStateOf(listOf("1", "2", "3")) }

var next by remember { mutableIntStateOf(4) }

Box(Modifier.fillMaxSize()) {
    TransformingLazyColumn(
        state = state,
        contentPadding = PaddingValues(5.dp),
        modifier = Modifier.background(Color.Black)
    ) {
        items(list.size, key = { list[it] }) {
            Text(
                "Item ${list[it]}",
                Modifier.animateItem().clickable {
                    list = list.filter { elem -> elem != list[it] }
                }
            )
        }
    }
    Text(
        "+",
        Modifier.align(Alignment.CenterStart).padding(horizontal = 5.dp).clickable {
            if (list.size < 25) list = list + "${next++}"
        }
    )
    Text(
        "S",
        Modifier.align(Alignment.CenterEnd).padding(horizontal = 5.dp).clickable {
            list = list.shuffled()
        }
    )
}
Parameters
fadeInSpec: FiniteAnimationSpec<Float>? = spring(stiffness = Spring.StiffnessMediumLow)

an animation spec to use for animating the item appearance. When null is provided the item will appear without animations.

placementSpec: FiniteAnimationSpec<IntOffset>? = spring( stiffness = Spring.StiffnessMediumLow, visibilityThreshold = IntOffset.VisibilityThreshold )

an animation spec that will be used to animate the item placement. Aside from item reordering all other position changes caused by events like arrangement or alignment changes will also be animated. When null is provided no animations will happen.

fadeOutSpec: FiniteAnimationSpec<Float>? = spring(stiffness = Spring.StiffnessMediumLow)

an animation spec to use for animating the item disappearance. When null is provided the item will be disappearance without animations.

fun Modifier.transformedHeight(
    heightProvider: (measuredHeight: Int, scrollProgress: TransformingLazyColumnItemScrollProgress) -> Int
): Modifier

Applies the new height of the item depending on its scroll progress and measured height.

Parameters
heightProvider: (measuredHeight: Int, scrollProgress: TransformingLazyColumnItemScrollProgress) -> Int

The transformation to be applied. The first parameter is the height of the item returned during measurement. The second parameter is the scroll progress of the item. This lambda should not read from any state values.

Public properties

val GraphicsLayerScope.scrollProgressTransformingLazyColumnItemScrollProgress?

Scroll progress of the item before height transformation is applied using Modifier.transformedHeight. Is null for the item that is off screen.

val DrawScope.scrollProgressTransformingLazyColumnItemScrollProgress?

Scroll progress of the item before height transformation is applied using Modifier.transformedHeight. Is null for the item that is off screen.