Skip to content

Commit 81c1a2a

Browse files
authored
Animate image size on scroll (#390)
* Add animate image size on scroll example * Add simple comments and rename some variables * Apply Spotless * Add region tags --------- Co-authored-by: jakeroseman <[email protected]>
1 parent d081491 commit 81c1a2a

File tree

1 file changed

+118
-0
lines changed

1 file changed

+118
-0
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
* Copyright 2024 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.compose.snippets.images
18+
19+
import androidx.compose.foundation.Image
20+
import androidx.compose.foundation.layout.Box
21+
import androidx.compose.foundation.layout.fillMaxWidth
22+
import androidx.compose.foundation.layout.offset
23+
import androidx.compose.foundation.layout.padding
24+
import androidx.compose.foundation.layout.size
25+
import androidx.compose.foundation.lazy.LazyColumn
26+
import androidx.compose.material3.MaterialTheme
27+
import androidx.compose.material3.Text
28+
import androidx.compose.runtime.Composable
29+
import androidx.compose.runtime.getValue
30+
import androidx.compose.runtime.mutableFloatStateOf
31+
import androidx.compose.runtime.mutableStateOf
32+
import androidx.compose.runtime.remember
33+
import androidx.compose.runtime.setValue
34+
import androidx.compose.ui.Alignment
35+
import androidx.compose.ui.Modifier
36+
import androidx.compose.ui.geometry.Offset
37+
import androidx.compose.ui.graphics.Color
38+
import androidx.compose.ui.graphics.graphicsLayer
39+
import androidx.compose.ui.graphics.painter.ColorPainter
40+
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
41+
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
42+
import androidx.compose.ui.input.nestedscroll.nestedScroll
43+
import androidx.compose.ui.tooling.preview.Preview
44+
import androidx.compose.ui.unit.Dp
45+
import androidx.compose.ui.unit.IntOffset
46+
import androidx.compose.ui.unit.dp
47+
48+
// [START android_compose_images_imageresizeonscrollexample]
49+
@Composable
50+
fun ImageResizeOnScrollExample(
51+
modifier: Modifier = Modifier,
52+
maxImageSize: Dp = 300.dp,
53+
minImageSize: Dp = 100.dp
54+
) {
55+
var currentImageSize by remember { mutableStateOf(maxImageSize) }
56+
var imageScale by remember { mutableFloatStateOf(1f) }
57+
58+
val nestedScrollConnection = remember {
59+
object : NestedScrollConnection {
60+
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
61+
// Calculate the change in image size based on scroll delta
62+
val delta = available.y
63+
val newImageSize = currentImageSize + delta.dp
64+
val previousImageSize = currentImageSize
65+
66+
// Constrain the image size within the allowed bounds
67+
currentImageSize = newImageSize.coerceIn(minImageSize, maxImageSize)
68+
val consumed = currentImageSize - previousImageSize
69+
70+
// Calculate the scale for the image
71+
imageScale = currentImageSize / maxImageSize
72+
73+
// Return the consumed scroll amount
74+
return Offset(0f, consumed.value)
75+
}
76+
}
77+
}
78+
79+
Box(Modifier.nestedScroll(nestedScrollConnection)) {
80+
LazyColumn(
81+
Modifier
82+
.fillMaxWidth()
83+
.padding(15.dp)
84+
.offset {
85+
IntOffset(0, currentImageSize.roundToPx())
86+
}
87+
) {
88+
// Placeholder list items
89+
items(100, key = { it }) {
90+
Text(
91+
text = "Item: $it",
92+
style = MaterialTheme.typography.bodyLarge
93+
)
94+
}
95+
}
96+
97+
Image(
98+
painter = ColorPainter(Color.Red),
99+
contentDescription = "Red color image",
100+
Modifier
101+
.size(maxImageSize)
102+
.align(Alignment.TopCenter)
103+
.graphicsLayer {
104+
scaleX = imageScale
105+
scaleY = imageScale
106+
// Center the image vertically as it scales
107+
translationY = -(maxImageSize.toPx() - currentImageSize.toPx()) / 2f
108+
}
109+
)
110+
}
111+
}
112+
// [END android_compose_images_imageresizeonscrollexample]
113+
114+
@Preview(showBackground = true)
115+
@Composable
116+
private fun ImageSizeOnScrollScreenPreview() {
117+
ImageResizeOnScrollExample()
118+
}

0 commit comments

Comments
 (0)