Skip to content

Commit 0fdecdb

Browse files
committed
feat: Adicionado Lottie API para animações com json
1 parent 7c9fefe commit 0fdecdb

File tree

7 files changed

+279
-57
lines changed

7 files changed

+279
-57
lines changed

app/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ android {
7474
}
7575

7676
dependencies {
77+
78+
implementation (libs.lottie.compose)
7779
implementation(libs.androidx.foundation)
7880

7981
implementation(platform(libs.firebase.bom))

app/src/main/java/com/paradoxo/threadscompose/MainActivity.kt

Lines changed: 198 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,16 @@ import androidx.compose.animation.core.spring
1111
import androidx.compose.animation.core.tween
1212
import androidx.compose.foundation.ExperimentalFoundationApi
1313
import androidx.compose.foundation.Image
14+
import androidx.compose.foundation.background
15+
import androidx.compose.foundation.clickable
1416
import androidx.compose.foundation.gestures.AnchoredDraggableState
1517
import androidx.compose.foundation.gestures.DraggableAnchors
1618
import androidx.compose.foundation.gestures.Orientation
1719
import androidx.compose.foundation.gestures.anchoredDraggable
1820
import androidx.compose.foundation.gestures.animateTo
1921
import androidx.compose.foundation.gestures.detectTransformGestures
2022
import androidx.compose.foundation.gestures.detectVerticalDragGestures
23+
import androidx.compose.foundation.interaction.MutableInteractionSource
2124
import androidx.compose.foundation.layout.Arrangement
2225
import androidx.compose.foundation.layout.Box
2326
import androidx.compose.foundation.layout.Column
@@ -27,6 +30,8 @@ import androidx.compose.foundation.layout.Spacer
2730
import androidx.compose.foundation.layout.fillMaxHeight
2831
import androidx.compose.foundation.layout.fillMaxSize
2932
import androidx.compose.foundation.layout.fillMaxWidth
33+
import androidx.compose.foundation.layout.height
34+
import androidx.compose.foundation.layout.navigationBarsPadding
3035
import androidx.compose.foundation.layout.offset
3136
import androidx.compose.foundation.layout.padding
3237
import androidx.compose.foundation.layout.size
@@ -38,12 +43,14 @@ import androidx.compose.material3.NavigationBar
3843
import androidx.compose.material3.NavigationBarItem
3944
import androidx.compose.material3.NavigationBarItemDefaults
4045
import androidx.compose.material3.Scaffold
46+
import androidx.compose.material3.Slider
4147
import androidx.compose.material3.Text
4248
import androidx.compose.runtime.Composable
4349
import androidx.compose.runtime.LaunchedEffect
4450
import androidx.compose.runtime.State
4551
import androidx.compose.runtime.collectAsState
4652
import androidx.compose.runtime.getValue
53+
import androidx.compose.runtime.mutableFloatStateOf
4754
import androidx.compose.runtime.mutableStateOf
4855
import androidx.compose.runtime.remember
4956
import androidx.compose.runtime.rememberCoroutineScope
@@ -75,6 +82,11 @@ import androidx.navigation.compose.composable
7582
import androidx.navigation.compose.currentBackStackEntryAsState
7683
import androidx.navigation.compose.rememberNavController
7784
import androidx.navigation.navigation
85+
import com.airbnb.lottie.compose.LottieAnimation
86+
import com.airbnb.lottie.compose.LottieCompositionSpec
87+
import com.airbnb.lottie.compose.LottieConstants
88+
import com.airbnb.lottie.compose.rememberLottieAnimatable
89+
import com.airbnb.lottie.compose.rememberLottieComposition
7890
import com.facebook.Profile
7991
import com.google.firebase.auth.ktx.auth
8092
import com.google.firebase.ktx.Firebase
@@ -106,12 +118,15 @@ class MainActivity : ComponentActivity() {
106118
super.onCreate(savedInstanceState)
107119
WindowCompat.setDecorFitsSystemWindows(window, false)
108120

109-
val testMode = false
121+
val testMode = true
110122

111123
if (testMode) {
112124
setContent {
113-
Box {
114-
FeedScreen(posts = SampleData().posts)
125+
Box(
126+
Modifier.fillMaxSize(),
127+
contentAlignment = Alignment.Center
128+
) {
129+
LottieStyles()
115130
}
116131
}
117132
} else {
@@ -164,6 +179,186 @@ class MainActivity : ComponentActivity() {
164179
}
165180
}
166181

182+
@Composable
183+
private fun LottieStyles() {
184+
val url =
185+
"https://lottie.host/a2a247fa-25e6-4884-b30c-47af6bb0ce31/3Bz9KEEqBj.json"
186+
187+
val sampleTest = 3
188+
when (sampleTest) {
189+
1 -> {
190+
val composition by rememberLottieComposition(
191+
spec = LottieCompositionSpec.Url(
192+
url
193+
)
194+
)
195+
196+
LottieAnimation(
197+
composition = composition,
198+
iterations = LottieConstants.IterateForever
199+
)
200+
}
201+
202+
2 -> {
203+
val anim = rememberLottieAnimatable()
204+
val composition by rememberLottieComposition(
205+
LottieCompositionSpec.Url(url)
206+
)
207+
var sliderGestureProgress: Float? by remember { mutableStateOf(null) }
208+
LaunchedEffect(composition, sliderGestureProgress) {
209+
when (val p = sliderGestureProgress) {
210+
null -> anim.animate(
211+
composition,
212+
iterations = 0,
213+
initialProgress = anim.progress,
214+
continueFromPreviousAnimate = false,
215+
)
216+
217+
else -> anim.snapTo(progress = p)
218+
}
219+
}
220+
Box(Modifier.padding(bottom = 32.dp)) {
221+
LottieAnimation(anim.composition, { anim.progress })
222+
Slider(
223+
value = sliderGestureProgress ?: anim.progress,
224+
onValueChange = { sliderGestureProgress = it },
225+
onValueChangeFinished = { sliderGestureProgress = null },
226+
modifier = Modifier
227+
.align(Alignment.BottomCenter)
228+
.padding(bottom = 8.dp)
229+
)
230+
}
231+
}
232+
233+
3 -> {
234+
var previsousProgress by remember { mutableFloatStateOf(0f) }
235+
var speed by remember { mutableFloatStateOf(0f) }
236+
val composition by rememberLottieComposition(
237+
LottieCompositionSpec.RawRes(
238+
R.raw.logo_lines_animated
239+
)
240+
)
241+
val animatable = rememberLottieAnimatable()
242+
243+
LaunchedEffect(speed) {
244+
animatable.animate(
245+
composition,
246+
iteration = LottieConstants.IterateForever,
247+
speed = speed,
248+
initialProgress = previsousProgress,
249+
)
250+
}
251+
val interactionSource = remember { MutableInteractionSource() }
252+
253+
LottieAnimation(
254+
composition = composition,
255+
progress = { animatable.progress },
256+
modifier = Modifier
257+
.clickable(
258+
interactionSource = interactionSource,
259+
indication = null
260+
) {
261+
speed = if (speed == 0f) 1f else 0f
262+
previsousProgress = animatable.progress
263+
}
264+
)
265+
}
266+
267+
4 -> {
268+
var previsousProgress by remember { mutableStateOf(0f) }
269+
var velocity by remember { mutableStateOf(0f) }
270+
var shouldPlay by remember { mutableStateOf(true) }
271+
val composition by rememberLottieComposition(
272+
LottieCompositionSpec.Url(
273+
url
274+
)
275+
)
276+
val animatable = rememberLottieAnimatable()
277+
278+
// LaunchedEffect(composition, shouldPlay) {
279+
// if (composition == null || !shouldPlay) return@LaunchedEffect
280+
// animatable.animate(
281+
// composition,
282+
// iteration = LottieConstants.IterateForever,
283+
// )
284+
// }
285+
286+
LaunchedEffect(shouldPlay) {
287+
animatable.animate(
288+
composition,
289+
iteration = LottieConstants.IterateForever,
290+
speed = velocity,
291+
initialProgress = previsousProgress,
292+
)
293+
}
294+
val interactionSource = remember { MutableInteractionSource() }
295+
296+
297+
LottieAnimation(
298+
composition = composition,
299+
progress = { animatable.progress },
300+
modifier = Modifier
301+
.clickable(
302+
interactionSource = interactionSource,
303+
indication = null
304+
) {
305+
shouldPlay = !shouldPlay
306+
velocity = if (velocity == 0f) 1f else 0f
307+
previsousProgress = animatable.progress
308+
}
309+
)
310+
311+
Text(
312+
text = "Progresso: ${animatable.progress}",
313+
Modifier.offset(y = (-300).dp)
314+
)
315+
}
316+
317+
5 -> {
318+
val anim = rememberLottieAnimatable()
319+
val composition by rememberLottieComposition(
320+
LottieCompositionSpec.Url(
321+
url
322+
)
323+
)
324+
var speed by remember { mutableStateOf(1f) }
325+
LaunchedEffect(composition, speed) {
326+
anim.animate(
327+
composition,
328+
iterations = LottieConstants.IterateForever,
329+
speed = speed,
330+
initialProgress = anim.progress,
331+
)
332+
}
333+
Column(
334+
Modifier.navigationBarsPadding()
335+
) {
336+
Box {
337+
LottieAnimation(composition, { anim.progress })
338+
Slider(
339+
value = speed,
340+
onValueChange = { speed = it },
341+
valueRange = -3f..3f,
342+
modifier = Modifier
343+
.align(Alignment.BottomCenter)
344+
.padding(bottom = 8.dp)
345+
)
346+
Box(
347+
modifier = Modifier
348+
.align(Alignment.BottomCenter)
349+
.padding(bottom = 24.dp)
350+
.size(width = 1.dp, height = 16.dp)
351+
.background(Color.Black)
352+
)
353+
}
354+
Spacer(modifier = Modifier.height(32.dp))
355+
}
356+
357+
358+
}
359+
}
360+
}
361+
167362
@Composable
168363
fun ThreadsApp(
169364
content: @Composable (PaddingValues) -> Unit,

app/src/main/java/com/paradoxo/threadscompose/ui/Components.kt

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@ import androidx.compose.ui.Modifier
3131
import androidx.compose.ui.draw.clip
3232
import androidx.compose.ui.graphics.Color
3333
import androidx.compose.ui.layout.ContentScale
34+
import androidx.compose.ui.platform.LocalContext
3435
import androidx.compose.ui.res.painterResource
3536
import androidx.compose.ui.text.font.FontWeight
3637
import androidx.compose.ui.tooling.preview.Preview
3738
import androidx.compose.ui.unit.dp
3839
import coil.compose.AsyncImage
40+
import coil.request.ImageRequest
3941
import com.paradoxo.threadscompose.R
4042
import com.paradoxo.threadscompose.model.Post
4143
import com.paradoxo.threadscompose.sampleData.SampleData
@@ -68,7 +70,10 @@ fun PostItem(
6870
horizontalAlignment = Alignment.CenterHorizontally
6971
) {
7072
AsyncImage(
71-
model = post.userAccount.imageProfileUrl,
73+
model = ImageRequest.Builder(LocalContext.current)
74+
.data(post.userAccount.imageProfileUrl)
75+
.crossfade(true)
76+
.build(),
7277
placeholder = painterResource(id = R.drawable.placeholder_image),
7378
error = painterResource(id = R.drawable.placeholder_image),
7479
contentDescription = "avatar",
@@ -138,7 +143,10 @@ fun PostItem(
138143
items(post.medias) { media ->
139144
Row {
140145
AsyncImage(
141-
model = media,
146+
model = ImageRequest.Builder(LocalContext.current)
147+
.data(media)
148+
.crossfade(true)
149+
.build(),
142150
placeholder = painterResource(id = R.drawable.placeholder_image),
143151
error = painterResource(id = R.drawable.placeholder_image),
144152
contentDescription = "avatar",
@@ -302,7 +310,10 @@ private fun ContainerOneProfilePic(
302310
Modifier.padding(horizontal = 8.dp, vertical = 16.dp)
303311
) {
304312
AsyncImage(
305-
model = profilePicAuthor,
313+
model = ImageRequest.Builder(LocalContext.current)
314+
.data(profilePicAuthor)
315+
.crossfade(true)
316+
.build(),
306317
contentDescription = "avatar",
307318
modifier = Modifier
308319
.size(22.dp)

0 commit comments

Comments
 (0)