Last active
August 13, 2022 06:30
-
-
Save SmartToolFactory/01df080eb6c44c9e1df2f4b675121dac to your computer and use it in GitHub Desktop.
Revisions
-
SmartToolFactory revised this gist
Aug 13, 2022 . 1 changed file with 51 additions and 22 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,37 @@ package com.smarttoolfactory.composeimage import androidx.compose.animation.core.* import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.Button import androidx.compose.material.Text import androidx.compose.material.TextField import androidx.compose.runtime.* import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.shadow import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch import java.util.* import kotlin.math.abs @OptIn(ExperimentalFoundationApi::class) @Composable private fun AnimatedList() { @@ -116,7 +150,20 @@ private fun AnimatedList() { .fillMaxWidth(), onClick = { animate = true // ALTERNATIVE with Animatable // val from = try { // Integer.parseInt(fromString) // } catch (e: Exception) { // 0 // } // // val to = try { // Integer.parseInt(toString) // } catch (e: Exception) { // 0 // } // alternativeAnimate(from, to, coroutineScope, animatable, items) } ) { Text("Swap") @@ -125,45 +172,29 @@ private fun AnimatedList() { } private fun alternativeAnimate( from: Int, to: Int, coroutineScope: CoroutineScope, animatable: Animatable<Int, AnimationVector1D>, items: SnapshotStateList<MyData> ) { val difference = from - to var currentValue: Int = from coroutineScope.launch { animatable.snapTo(from) animatable.animateTo(to, tween(350 * abs(difference), easing = LinearEasing), block = { val nextValue = this.value if (abs(currentValue - nextValue) == 1) { swap(items, currentValue, nextValue) currentValue = nextValue } } ) } } @@ -198,8 +229,6 @@ private fun animatedSwap( // lazyListState.animateScrollToItem(0) // } delay(350) } onFinish() } -
SmartToolFactory created this gist
Aug 11, 2022 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,221 @@ @OptIn(ExperimentalFoundationApi::class) @Composable private fun AnimatedList() { Column(modifier = Modifier.fillMaxSize()) { val items: SnapshotStateList<MyData> = remember { mutableStateListOf<MyData>().apply { repeat(20) { add(MyData(uuid = UUID.randomUUID().toString(), "Row $it")) } } } val lazyListState = rememberLazyListState() LazyColumn( modifier = Modifier .fillMaxWidth() .weight(1f), state = lazyListState, contentPadding = PaddingValues(horizontal = 10.dp, vertical = 0.dp), verticalArrangement = Arrangement.spacedBy(4.dp) ) { items( items = items, key = { it.uuid } ) { Row( modifier = Modifier .animateItemPlacement( tween(durationMillis = 200) ) .shadow(1.dp, RoundedCornerShape(8.dp)) .background(Color.White) .fillMaxWidth() .padding(8.dp), verticalAlignment = Alignment.CenterVertically ) { Image( modifier = Modifier .clip(RoundedCornerShape(10.dp)) .size(50.dp), painter = painterResource(id = R.drawable.landscape1), contentScale = ContentScale.FillBounds, contentDescription = null ) Spacer(modifier = Modifier.width(10.dp)) Text(it.value, fontSize = 18.sp) } } } var fromString by remember { mutableStateOf("7") } var toString by remember { mutableStateOf("3") } var animate by remember { mutableStateOf(false) } val coroutineScope = rememberCoroutineScope() val animatable = remember { Animatable(0, IntToVector) } if (animate) { val from = try { Integer.parseInt(fromString) } catch (e: Exception) { 0 } val to = try { Integer.parseInt(toString) } catch (e: Exception) { 0 } animatedSwap( lazyListState = lazyListState, items = items, from = from, to = to ) { animate = false } } Row(modifier = Modifier.fillMaxWidth()) { TextField( value = fromString, onValueChange = { fromString = it }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number) ) TextField( value = toString, onValueChange = { toString = it }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number) ) } Button( modifier = Modifier .padding(8.dp) .fillMaxWidth(), onClick = { animate = true // alternativeAnimate(fromString, toString, coroutineScope, animatable, items) } ) { Text("Swap") } } } private fun alternativeAnimate( fromString: String, toString: String, coroutineScope: CoroutineScope, animatable: Animatable<Int, AnimationVector1D>, items: SnapshotStateList<MyData> ) { val from = try { Integer.parseInt(fromString) } catch (e: Exception) { 0 } val to = try { Integer.parseInt(toString) } catch (e: Exception) { 0 } val difference = from - to val increasing = difference < 0 var currentValue: Int = from coroutineScope.launch { animatable.snapTo(from) animatable.animateTo(to, tween(350 * abs(difference)), block = { val nextValue = this.value if (abs(currentValue - nextValue) == 1) { println("🔥difference: $difference, from: $from, to: $to, Animating current: $currentValue, nextValue: $nextValue") swap(items, currentValue, nextValue) currentValue = nextValue } } ) } } @Composable private fun animatedSwap( lazyListState: LazyListState, items: SnapshotStateList<MyData>, from: Int, to: Int, onFinish: () -> Unit ) { LaunchedEffect(key1 = Unit) { val difference = from - to val increasing = difference < 0 var currentValue: Int = from repeat(abs(difference)) { val temp = currentValue if (increasing) { currentValue++ } else { currentValue-- } swap(items, temp, currentValue) // if (!increasing && currentValue == 0) { // lazyListState.animateScrollToItem(0) // } delay(350) } onFinish() } } private fun swap(list: SnapshotStateList<MyData>, from: Int, to: Int) { val size = list.size if (from in 0 until size && to in 0 until size) { val temp = list[from] list[from] = list[to] list[to] = temp } } class MyData(val uuid: String, val value: String) val IntToVector: TwoWayConverter<Int, AnimationVector1D> = TwoWayConverter({ AnimationVector1D(it.toFloat()) }, { it.value.toInt() })