简体   繁体   中英

animation o a lazycolumn android

I have a list with 10 items one of them have this elements "rankingCurrentPlace" , "rankingPastPlace" and "isUser:true" .

What i need to do its an animation on the lazycolumn if the api esponse is like this "isUser:true" , "rankingPastPlace:3" , "rankingCurrentPlace:7"

i need to show an animation in the list where the row starts in the third place and descend to the seventh place

is there a way to do this?

this is what I actually have

    LazyColumn(
        contentPadding = PaddingValues(horizontal = 10.dp, vertical = 0.dp),

    ) {
        items(
            items = leaderboard,
            key = { leaderBoard ->
                leaderBoard.rankingPlace
            }
        ) { leaderBoard ->
                RowComposable( modifier = Modifier
                    .fillMaxWidth(),
                    topicsItem = leaderBoard,)                
        }

I suggest you to get your items from a data class. If your other items does not contain the variables you mentioned you can make them nullable in data class and put a condition checker in your lazycolumn

Like this

data class Items(
   val otherItems: Other,
   val rankingCurrentPlace: Int?,
   val rankingLastPlace: Int?,
   val isUser: Boolean?
)

Then you can make a list from this data class and pass it to lazycolumn

LazyColumn{
    items(list){
        (elements with condition)
    }
}

This function works except when swapping with first item. Added a delay but it looks like not matching swap. Other than that works as expected. If need to move to items that are not in screen we can use lazyListState.layoutInfo.visibleItemsInfo and compare with initial item and scroll to it before animation

1.Have a SnapshotStateList of data to trigger recomposition when we swap 2 items

class MyData(val uuid: String, val value: String)

val items: SnapshotStateList<MyData> = remember {
    mutableStateListOf<MyData>().apply {
        repeat(20) {
            add(MyData( uuid = UUID.randomUUID().toString(), "Row $it"))
        }
    }
}

2.Function to swap items It doesn't look pretty and when last swap is first item it doesn't scroll to start, will check again

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
    }
}

3.Function to swap items one by one

@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) {
                delay(300)
                lazyListState.scrollToItem(0)
            }
            delay(350)

        }
        onFinish()
    }
}

4.List with items that have Modifier.animateItemPlacement()

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)
        }
    }
}

Demo

@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) }



        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
            }
        ) {
            Text("Swap")
        }
    }
}

Result

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM