Skip to content

Commit 6cc9701

Browse files
committed
Add animate image size on scroll example
1 parent d081491 commit 6cc9701

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package com.example.compose.snippets.images
2+
3+
import androidx.compose.foundation.Image
4+
import androidx.compose.foundation.layout.Box
5+
import androidx.compose.foundation.layout.fillMaxWidth
6+
import androidx.compose.foundation.layout.offset
7+
import androidx.compose.foundation.layout.padding
8+
import androidx.compose.foundation.layout.size
9+
import androidx.compose.foundation.lazy.LazyColumn
10+
import androidx.compose.material3.MaterialTheme
11+
import androidx.compose.material3.Text
12+
import androidx.compose.runtime.Composable
13+
import androidx.compose.runtime.getValue
14+
import androidx.compose.runtime.mutableFloatStateOf
15+
import androidx.compose.runtime.mutableStateOf
16+
import androidx.compose.runtime.remember
17+
import androidx.compose.runtime.setValue
18+
import androidx.compose.ui.Alignment
19+
import androidx.compose.ui.Modifier
20+
import androidx.compose.ui.geometry.Offset
21+
import androidx.compose.ui.graphics.Color
22+
import androidx.compose.ui.graphics.graphicsLayer
23+
import androidx.compose.ui.graphics.painter.ColorPainter
24+
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
25+
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
26+
import androidx.compose.ui.input.nestedscroll.nestedScroll
27+
import androidx.compose.ui.tooling.preview.Preview
28+
import androidx.compose.ui.unit.Dp
29+
import androidx.compose.ui.unit.IntOffset
30+
import androidx.compose.ui.unit.dp
31+
32+
@Composable
33+
fun ImageResizeOnScrollExample(
34+
modifier: Modifier = Modifier,
35+
maxImgSize: Dp = 300.dp,
36+
minImgSize: Dp = 100.dp
37+
) {
38+
var currentImgSize by remember { mutableStateOf(maxImgSize) }
39+
var scale by remember { mutableFloatStateOf(1f) }
40+
41+
val nestedScrollConnection = remember {
42+
object : NestedScrollConnection {
43+
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
44+
// Calculate the change in image size based on scroll delta
45+
val delta = available.y
46+
val newImgSize = currentImgSize + delta.dp
47+
val previousImgSize = currentImgSize
48+
49+
// Constrain the image size within the allowed bounds
50+
currentImgSize = newImgSize.coerceIn(minImgSize, maxImgSize)
51+
val consumed = currentImgSize - previousImgSize
52+
53+
// Calculate the scale for the image
54+
scale = currentImgSize / maxImgSize
55+
56+
// Return the consumed scroll amount
57+
return Offset(0f, consumed.value)
58+
}
59+
}
60+
}
61+
62+
Box(Modifier.nestedScroll(nestedScrollConnection)) {
63+
LazyColumn(
64+
Modifier
65+
.fillMaxWidth()
66+
.padding(15.dp)
67+
.offset {
68+
IntOffset(0, currentImgSize.roundToPx())
69+
}
70+
) {
71+
// Placeholder list items
72+
items(100, key = { it }) {
73+
Text(
74+
text = "Item: $it",
75+
style = MaterialTheme.typography.bodyLarge
76+
)
77+
}
78+
}
79+
80+
Image(
81+
painter = ColorPainter(Color.Red),
82+
contentDescription = "Red color image",
83+
Modifier
84+
.size(maxImgSize)
85+
.align(Alignment.TopCenter)
86+
.graphicsLayer {
87+
scaleX = scale
88+
scaleY = scale
89+
translationY = -(maxImgSize.toPx() - currentImgSize.toPx()) / 2f
90+
}
91+
)
92+
}
93+
}
94+
95+
96+
@Preview(showBackground = true)
97+
@Composable
98+
private fun ImageSizeOnScrollScreenPreview() {
99+
ImageResizeOnScrollExample()
100+
}

0 commit comments

Comments
 (0)