Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can Android Studio launch the inline fun <T> key()?

The Code A is from the offical sample project here.

The Code B is from Android Studio source code.

I have searched the article about the function key by Google, but I can't find more details about it.

How can Android Studio launch the inline fun <T> key()? Why can't the author use Code C to launch directly?

Code A

key(detailPost.id) {
    LazyColumn(
        state = detailLazyListState,
        contentPadding = contentPadding,
        modifier = Modifier
            .padding(horizontal = 16.dp)
            .fillMaxSize()
            .notifyInput {
                onInteractWithDetail(detailPost.id)
            }
    ) {
        stickyHeader {
            val context = LocalContext.current
            PostTopBar(
                isFavorite = hasPostsUiState.favorites.contains(detailPost.id),
                onToggleFavorite = { onToggleFavorite(detailPost.id) },
                onSharePost = { sharePost(detailPost, context) },
                modifier = Modifier.fillMaxWidth().wrapContentWidth(Alignment.End)
            )
        }
        postContentItems(detailPost)
    }
}

Code B

@Composable
inline fun <T> key(
    @Suppress("UNUSED_PARAMETER")
    vararg keys: Any?,
    block: @Composable () -> T
) = block()

Code C

LazyColumn(
    state = detailLazyListState,
    contentPadding = contentPadding,
    modifier = Modifier
        .padding(horizontal = 16.dp)
        .fillMaxSize()
        .notifyInput {
            onInteractWithDetail(detailPost.id)
        }
) {
    stickyHeader {
        val context = LocalContext.current
        PostTopBar(
            isFavorite = hasPostsUiState.favorites.contains(detailPost.id),
            onToggleFavorite = { onToggleFavorite(detailPost.id) },
            onSharePost = { sharePost(detailPost, context) },
            modifier = Modifier.fillMaxWidth().wrapContentWidth(Alignment.End)
        )
    }
    postContentItems(detailPost)
}
like image 200
HelloCW Avatar asked Oct 24 '25 00:10

HelloCW


1 Answers

From key documentation:

key is a utility composable that is used to "group" or "key" a block of execution inside of a composition. This is sometimes needed for correctness inside of control-flow that may cause a given composable invocation to execute more than once during composition.

It also contains several examples, so check it out.

Here is a basic example of the usefulness of it. Suppose you have the following Composable. I added DisposableEffect to track its lifecycle.

@Composable
fun SomeComposable(text: String) {
    DisposableEffect(text) {
        println("appear $text")
        onDispose {
            println("onDispose $text")
        }
    }
    Text(text)
}

And here's usage:

val items = remember { List(10) { it } }
var offset by remember {
    mutableStateOf(0)
}
Button(onClick = {
    println("click")
    offset += 1
}) {
}
Column {
    items.subList(offset, offset + 3).forEach { item ->
        key(item) {
            SomeComposable(item.toString())
        }
    }
}

I only display two list items, and move the window each time the button is clicked.

Without key, each click will remove all previous views and create new ones.

But with key(item), only the disappeared item disappears, and the items that are still on the screen are reused without recomposition.

Here are the logs:

appear 0
appear 1
appear 2
click
onDispose 0
appear 3
click
onDispose 1
appear 4
click
onDispose 2
appear 5
like image 85
Philip Dukhov Avatar answered Oct 26 '25 14:10

Philip Dukhov