-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy pathKamelImage.kt
106 lines (103 loc) · 4.4 KB
/
KamelImage.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package io.kamel.image
import androidx.compose.animation.Crossfade
import androidx.compose.animation.core.FiniteAnimationSpec
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.DefaultAlpha
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import io.kamel.core.ExperimentalKamelApi
import io.kamel.core.Resource
/**
* A composable that is used to display a [Painter] resource.
* To load an image resource asynchronously, use [asyncPainterResource].
* @param resource The [Resource] that needs to be displayed.
* @param modifier The modifier that is applied to the [Box].
* @param onLoading Composable which is used while the image is in [Resource.Loading] state.
* @param onFailure Composable which is used while the image is in [Resource.Failure] state.
* @param contentAlignment The default alignment inside the Box.
* @param animationSpec a [FiniteAnimationSpec] to be used in [Crossfade] animation, or null to be disabled.
* The rest is the default [Image] parameters.
*/
@OptIn(ExperimentalKamelApi::class)
@Composable
public fun KamelImage(
resource: Resource<Painter>,
contentDescription: String?,
modifier: Modifier = Modifier,
alignment: Alignment = Alignment.Center,
contentScale: ContentScale = ContentScale.Fit,
alpha: Float = DefaultAlpha,
colorFilter: ColorFilter? = null,
onLoading: @Composable (BoxScope.(Float) -> Unit)? = null,
onFailure: @Composable (BoxScope.(Throwable) -> Unit)? = null,
contentAlignment: Alignment = Alignment.Center,
animationSpec: FiniteAnimationSpec<Float>? = null,
) {
val onSuccess: @Composable (BoxScope.(Painter) -> Unit) = { painter ->
Image(
painter,
contentDescription,
Modifier.fillMaxSize(),
alignment,
contentScale,
alpha,
colorFilter
)
}
KamelImageBox(
resource,
modifier,
contentAlignment,
animationSpec,
onLoading,
onFailure,
onSuccess,
)
}
/**
* A composable that is used to display a [Painter] resource.
* To load an image [Resource] asynchronously, use [asyncPainterResource].
* @param resource The [Resource] that needs to be displayed.
* @param modifier The modifier that is applied to the [Box].
* @param contentAlignment The default alignment inside the Box.
* @param animationSpec a [FiniteAnimationSpec] to be used in [Crossfade] animation, or null to be disabled.
* @param onLoading Composable which is used while the image is in [Resource.Loading] state.
* @param onFailure Composable which is used while the image is in [Resource.Failure] state.
* @param onSuccess Composable which is used while the image is in [Resource.Success] state.
*/
@ExperimentalKamelApi
@Composable
public fun KamelImageBox(
resource: Resource<Painter>,
modifier: Modifier = Modifier,
contentAlignment: Alignment = Alignment.Center,
animationSpec: FiniteAnimationSpec<Float>? = null,
onLoading: @Composable (BoxScope.(Float) -> Unit)? = null,
onFailure: @Composable (BoxScope.(Throwable) -> Unit)? = null,
onSuccess: @Composable BoxScope.(Painter) -> Unit,
) {
Box(modifier, contentAlignment) {
if (animationSpec != null) {
Crossfade(resource, animationSpec = animationSpec) { animatedResource ->
when (animatedResource) {
is Resource.Loading -> if (onLoading != null) onLoading(animatedResource.progress)
is Resource.Success -> onSuccess(animatedResource.value)
is Resource.Failure -> if (onFailure != null) onFailure(animatedResource.exception)
}
}
} else {
when (resource) {
is Resource.Loading -> if (onLoading != null) onLoading(resource.progress)
is Resource.Success -> onSuccess(resource.value)
is Resource.Failure -> if (onFailure != null) onFailure(resource.exception)
}
}
}
}