Skip to content

Commit 5a817fc

Browse files
authored
Merge pull request #2 from git-jr/dev-animations
Adição de logo animado através da Lottie API
2 parents bdc9e19 + 7239eaa commit 5a817fc

File tree

7 files changed

+392
-56
lines changed

7 files changed

+392
-56
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: 200 additions & 2 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
@@ -110,8 +122,11 @@ class MainActivity : ComponentActivity() {
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,189 @@ 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 previousProgress by remember { mutableFloatStateOf(0f) }
235+
var speed by remember { mutableFloatStateOf(1f) }
236+
val composition by rememberLottieComposition(
237+
LottieCompositionSpec.RawRes(
238+
R.raw.logo_lines_animated
239+
)
240+
)
241+
val animatable = rememberLottieAnimatable()
242+
243+
val context = LocalContext.current
244+
context.showMessage(animatable.isPlaying.toString())
245+
246+
LaunchedEffect(speed) {
247+
animatable.animate(
248+
composition,
249+
iteration = LottieConstants.IterateForever,
250+
speed = speed,
251+
initialProgress = previousProgress,
252+
)
253+
}
254+
val interactionSource = remember { MutableInteractionSource() }
255+
256+
LottieAnimation(
257+
composition = composition,
258+
progress = { animatable.progress },
259+
modifier = Modifier
260+
.clickable(
261+
interactionSource = interactionSource,
262+
indication = null
263+
) {
264+
speed = if (speed == 0f) 1f else 0f
265+
previousProgress = animatable.progress
266+
}
267+
)
268+
}
269+
270+
4 -> {
271+
var previsousProgress by remember { mutableStateOf(0f) }
272+
var velocity by remember { mutableStateOf(0f) }
273+
var shouldPlay by remember { mutableStateOf(true) }
274+
val composition by rememberLottieComposition(
275+
LottieCompositionSpec.Url(
276+
url
277+
)
278+
)
279+
val animatable = rememberLottieAnimatable()
280+
281+
// LaunchedEffect(composition, shouldPlay) {
282+
// if (composition == null || !shouldPlay) return@LaunchedEffect
283+
// animatable.animate(
284+
// composition,
285+
// iteration = LottieConstants.IterateForever,
286+
// )
287+
// }
288+
289+
LaunchedEffect(shouldPlay) {
290+
animatable.animate(
291+
composition,
292+
iteration = LottieConstants.IterateForever,
293+
speed = velocity,
294+
initialProgress = previsousProgress,
295+
)
296+
}
297+
val interactionSource = remember { MutableInteractionSource() }
298+
299+
300+
LottieAnimation(
301+
composition = composition,
302+
progress = { animatable.progress },
303+
modifier = Modifier
304+
.clickable(
305+
interactionSource = interactionSource,
306+
indication = null
307+
) {
308+
shouldPlay = !shouldPlay
309+
velocity = if (velocity == 0f) 1f else 0f
310+
previsousProgress = animatable.progress
311+
}
312+
)
313+
314+
Text(
315+
text = "Progresso: ${animatable.progress}",
316+
Modifier.offset(y = (-300).dp)
317+
)
318+
}
319+
320+
5 -> {
321+
val anim = rememberLottieAnimatable()
322+
val composition by rememberLottieComposition(
323+
LottieCompositionSpec.Url(
324+
url
325+
)
326+
)
327+
var speed by remember { mutableStateOf(1f) }
328+
LaunchedEffect(composition, speed) {
329+
anim.animate(
330+
composition,
331+
iterations = LottieConstants.IterateForever,
332+
speed = speed,
333+
initialProgress = anim.progress,
334+
)
335+
}
336+
Column(
337+
Modifier.navigationBarsPadding()
338+
) {
339+
Box {
340+
LottieAnimation(composition, { anim.progress })
341+
Slider(
342+
value = speed,
343+
onValueChange = { speed = it },
344+
valueRange = -3f..3f,
345+
modifier = Modifier
346+
.align(Alignment.BottomCenter)
347+
.padding(bottom = 8.dp)
348+
)
349+
Box(
350+
modifier = Modifier
351+
.align(Alignment.BottomCenter)
352+
.padding(bottom = 24.dp)
353+
.size(width = 1.dp, height = 16.dp)
354+
.background(Color.Black)
355+
)
356+
}
357+
Spacer(modifier = Modifier.height(32.dp))
358+
}
359+
360+
361+
}
362+
}
363+
}
364+
167365
@Composable
168366
fun ThreadsApp(
169367
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)